paygate-mcp 6.3.0 → 6.5.0

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/README.md CHANGED
@@ -90,6 +90,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
90
90
  - **Key Statistics** — `GET /keys/stats` returns aggregate statistics across all keys — total/active/suspended/expired/revoked counts, credit aggregates (allocated/spent/remaining), total calls, namespace and group breakdowns, optional `?namespace=` filter
91
91
  - **Rate Limit Status** — `GET /keys/rate-limit-status?key=...` returns the current rate limit window state for any key — global calls used/remaining/reset time, per-tool rate limits with individual usage, read-only (doesn't consume a call)
92
92
  - **Quota Status** — `GET /keys/quota-status?key=...` returns daily/monthly quota usage for any key — calls and credits used/remaining/limits, reset periods, quota source (per-key vs global vs none)
93
+ - **Credit History** — `GET /keys/credit-history?key=...` returns per-key credit mutation log — tracks initial allocation, topups, transfers (in/out), auto-topups, with type/limit/since filters, balance-before/after on every entry, newest-first ordering, capped at 100 entries per key
94
+ - **Spending Velocity** — `GET /keys/spending-velocity?key=...` returns credit burn rate and depletion forecast — credits/calls per hour/day, estimated depletion date, top tools by spend, configurable analysis window (1h–30d)
93
95
  - **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
94
96
  - **Webhook Events** — POST batched usage events to any URL for external billing/alerting
95
97
  - **Config File Mode** — Load all settings from a JSON file (`--config`)
@@ -1717,6 +1719,83 @@ curl "http://localhost:3402/keys/quota-status?key=pg_..." -H "X-Admin-Key: YOUR_
1717
1719
 
1718
1720
  `quotaSource` indicates where the quota is configured: `"per-key"` (key-level override), `"global"` (server-wide config), or `"none"` (no quota). When a limit is `0` (unlimited), `remaining` is `null`.
1719
1721
 
1722
+ ### Credit History
1723
+
1724
+ `GET /keys/credit-history?key=...` returns the credit mutation log for a key:
1725
+
1726
+ ```bash
1727
+ curl "http://localhost:3402/keys/credit-history?key=pg_..." -H "X-Admin-Key: YOUR_ADMIN_KEY"
1728
+
1729
+ # Filter by type, limit, or since timestamp
1730
+ curl "http://localhost:3402/keys/credit-history?key=pg_...&type=topup&limit=10" -H "X-Admin-Key: YOUR_ADMIN_KEY"
1731
+ ```
1732
+
1733
+ **Response:**
1734
+
1735
+ ```json
1736
+ {
1737
+ "key": "pg_abc123...",
1738
+ "name": "my-key",
1739
+ "currentBalance": 700,
1740
+ "totalEntries": 3,
1741
+ "entries": [
1742
+ {
1743
+ "timestamp": "2026-02-26T12:30:00.000Z",
1744
+ "type": "topup",
1745
+ "amount": 200,
1746
+ "balanceBefore": 500,
1747
+ "balanceAfter": 700
1748
+ },
1749
+ {
1750
+ "timestamp": "2026-02-26T12:00:00.000Z",
1751
+ "type": "initial",
1752
+ "amount": 500,
1753
+ "balanceBefore": 0,
1754
+ "balanceAfter": 500
1755
+ }
1756
+ ]
1757
+ }
1758
+ ```
1759
+
1760
+ Entry types: `initial`, `topup`, `transfer_in`, `transfer_out`, `auto_topup`, `deduction`, `refund`, `bulk_topup`. Entries are newest-first, capped at 100 per key. Transfers include a `memo` field when provided.
1761
+
1762
+ ### Spending Velocity
1763
+
1764
+ `GET /keys/spending-velocity?key=...` returns credit burn rate and depletion forecast:
1765
+
1766
+ ```bash
1767
+ curl "http://localhost:3402/keys/spending-velocity?key=pg_..." -H "X-Admin-Key: YOUR_ADMIN_KEY"
1768
+
1769
+ # Custom analysis window (default 24h, max 720h/30d)
1770
+ curl "http://localhost:3402/keys/spending-velocity?key=pg_...&window=48" -H "X-Admin-Key: YOUR_ADMIN_KEY"
1771
+ ```
1772
+
1773
+ **Response:**
1774
+
1775
+ ```json
1776
+ {
1777
+ "key": "pg_abc123...",
1778
+ "name": "my-key",
1779
+ "currentBalance": 750,
1780
+ "velocity": {
1781
+ "creditsPerHour": 12.5,
1782
+ "creditsPerDay": 300,
1783
+ "callsPerHour": 2.5,
1784
+ "callsPerDay": 60,
1785
+ "estimatedDepletionDate": "2026-03-01T18:00:00.000Z",
1786
+ "estimatedHoursRemaining": 60,
1787
+ "windowHours": 24,
1788
+ "dataPoints": 45
1789
+ },
1790
+ "topTools": [
1791
+ { "tool": "search", "calls": 30, "credits": 150 },
1792
+ { "tool": "generate", "calls": 15, "credits": 120 }
1793
+ ]
1794
+ }
1795
+ ```
1796
+
1797
+ `estimatedDepletionDate` and `estimatedHoursRemaining` are `null` when there's no spending activity. `topTools` shows the 5 highest-spend tools from usage data.
1798
+
1720
1799
  ### IP Allowlisting
1721
1800
 
1722
1801
  Restrict API keys to specific IP addresses or CIDR ranges:
@@ -0,0 +1,57 @@
1
+ /**
2
+ * CreditLedger — Per-key credit mutation history.
3
+ *
4
+ * Records credit balance changes (topup, deduction, transfer, auto-topup, refund,
5
+ * initial allocation) with before/after snapshots. Capped at last N entries per key.
6
+ */
7
+ export interface CreditEntry {
8
+ timestamp: string;
9
+ type: 'initial' | 'topup' | 'deduction' | 'transfer_in' | 'transfer_out' | 'auto_topup' | 'refund' | 'bulk_topup';
10
+ amount: number;
11
+ balanceBefore: number;
12
+ balanceAfter: number;
13
+ tool?: string;
14
+ memo?: string;
15
+ }
16
+ export declare class CreditLedger {
17
+ private entries;
18
+ private maxEntriesPerKey;
19
+ constructor(maxEntriesPerKey?: number);
20
+ /**
21
+ * Record a credit mutation for a key.
22
+ */
23
+ record(key: string, entry: Omit<CreditEntry, 'timestamp'>): void;
24
+ /**
25
+ * Get credit history for a key, newest first.
26
+ * Optionally filter by type and limit.
27
+ */
28
+ getHistory(key: string, opts?: {
29
+ type?: string;
30
+ limit?: number;
31
+ since?: string;
32
+ }): CreditEntry[];
33
+ /**
34
+ * Get entry count for a key.
35
+ */
36
+ count(key: string): number;
37
+ /**
38
+ * Clear all entries for a key.
39
+ */
40
+ clear(key: string): void;
41
+ /**
42
+ * Compute spending velocity and depletion forecast for a key.
43
+ * Analyzes credit debit entries (deduction, transfer_out) over a rolling window.
44
+ */
45
+ getSpendingVelocity(key: string, currentBalance: number, windowHours?: number): SpendingVelocity;
46
+ }
47
+ export interface SpendingVelocity {
48
+ creditsPerHour: number;
49
+ creditsPerDay: number;
50
+ callsPerHour: number;
51
+ callsPerDay: number;
52
+ estimatedDepletionDate: string | null;
53
+ estimatedHoursRemaining: number | null;
54
+ windowHours: number;
55
+ dataPoints: number;
56
+ }
57
+ //# sourceMappingURL=credit-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credit-ledger.d.ts","sourceRoot":"","sources":["../src/credit-ledger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,GAAG,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;IAClH,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,gBAAgB,CAAS;gBAErB,gBAAgB,SAAM;IAIlC;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,IAAI;IAehE;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,WAAW,EAAE;IAmBhG;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAI1B;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxB;;;OAGG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,SAAK,GAAG,gBAAgB;CAmE7F;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ /**
3
+ * CreditLedger — Per-key credit mutation history.
4
+ *
5
+ * Records credit balance changes (topup, deduction, transfer, auto-topup, refund,
6
+ * initial allocation) with before/after snapshots. Capped at last N entries per key.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.CreditLedger = void 0;
10
+ class CreditLedger {
11
+ entries = new Map();
12
+ maxEntriesPerKey;
13
+ constructor(maxEntriesPerKey = 100) {
14
+ this.maxEntriesPerKey = maxEntriesPerKey;
15
+ }
16
+ /**
17
+ * Record a credit mutation for a key.
18
+ */
19
+ record(key, entry) {
20
+ if (!this.entries.has(key)) {
21
+ this.entries.set(key, []);
22
+ }
23
+ const list = this.entries.get(key);
24
+ list.push({
25
+ ...entry,
26
+ timestamp: new Date().toISOString(),
27
+ });
28
+ // Cap at max entries
29
+ if (list.length > this.maxEntriesPerKey) {
30
+ list.splice(0, list.length - this.maxEntriesPerKey);
31
+ }
32
+ }
33
+ /**
34
+ * Get credit history for a key, newest first.
35
+ * Optionally filter by type and limit.
36
+ */
37
+ getHistory(key, opts) {
38
+ const list = this.entries.get(key);
39
+ if (!list || list.length === 0)
40
+ return [];
41
+ let result = [...list].reverse(); // newest first
42
+ if (opts?.type) {
43
+ result = result.filter(e => e.type === opts.type);
44
+ }
45
+ if (opts?.since) {
46
+ result = result.filter(e => e.timestamp >= opts.since);
47
+ }
48
+ if (opts?.limit && opts.limit > 0) {
49
+ result = result.slice(0, opts.limit);
50
+ }
51
+ return result;
52
+ }
53
+ /**
54
+ * Get entry count for a key.
55
+ */
56
+ count(key) {
57
+ return this.entries.get(key)?.length || 0;
58
+ }
59
+ /**
60
+ * Clear all entries for a key.
61
+ */
62
+ clear(key) {
63
+ this.entries.delete(key);
64
+ }
65
+ /**
66
+ * Compute spending velocity and depletion forecast for a key.
67
+ * Analyzes credit debit entries (deduction, transfer_out) over a rolling window.
68
+ */
69
+ getSpendingVelocity(key, currentBalance, windowHours = 24) {
70
+ const list = this.entries.get(key);
71
+ if (!list || list.length === 0) {
72
+ return {
73
+ creditsPerHour: 0,
74
+ creditsPerDay: 0,
75
+ callsPerHour: 0,
76
+ callsPerDay: 0,
77
+ estimatedDepletionDate: null,
78
+ estimatedHoursRemaining: null,
79
+ windowHours,
80
+ dataPoints: 0,
81
+ };
82
+ }
83
+ const now = Date.now();
84
+ const cutoff = new Date(now - windowHours * 3_600_000).toISOString();
85
+ // Debit types reduce balance
86
+ const debitTypes = new Set(['deduction', 'transfer_out']);
87
+ const debits = list.filter(e => debitTypes.has(e.type) && e.timestamp >= cutoff);
88
+ const totalDebited = debits.reduce((sum, e) => sum + e.amount, 0);
89
+ const debitCount = debits.length;
90
+ // Compute the actual time span of debits (if any)
91
+ let spanHours = windowHours;
92
+ if (debits.length >= 2) {
93
+ const oldest = new Date(debits[0].timestamp).getTime();
94
+ const newest = new Date(debits[debits.length - 1].timestamp).getTime();
95
+ const span = (newest - oldest) / 3_600_000;
96
+ if (span > 0)
97
+ spanHours = span;
98
+ }
99
+ else if (debits.length === 1) {
100
+ // Single debit — use time from debit to now as span
101
+ const debitTime = new Date(debits[0].timestamp).getTime();
102
+ const span = (now - debitTime) / 3_600_000;
103
+ if (span > 0.01)
104
+ spanHours = span; // At least ~36 seconds
105
+ }
106
+ const creditsPerHour = debits.length > 0 ? totalDebited / spanHours : 0;
107
+ const creditsPerDay = creditsPerHour * 24;
108
+ const callsPerHour = debits.length > 0 ? debitCount / spanHours : 0;
109
+ const callsPerDay = callsPerHour * 24;
110
+ let estimatedDepletionDate = null;
111
+ let estimatedHoursRemaining = null;
112
+ if (creditsPerHour > 0 && currentBalance > 0) {
113
+ estimatedHoursRemaining = Math.round((currentBalance / creditsPerHour) * 100) / 100;
114
+ const depletionMs = now + estimatedHoursRemaining * 3_600_000;
115
+ estimatedDepletionDate = new Date(depletionMs).toISOString();
116
+ }
117
+ else if (currentBalance <= 0) {
118
+ estimatedHoursRemaining = 0;
119
+ estimatedDepletionDate = new Date(now).toISOString();
120
+ }
121
+ return {
122
+ creditsPerHour: Math.round(creditsPerHour * 100) / 100,
123
+ creditsPerDay: Math.round(creditsPerDay * 100) / 100,
124
+ callsPerHour: Math.round(callsPerHour * 100) / 100,
125
+ callsPerDay: Math.round(callsPerDay * 100) / 100,
126
+ estimatedDepletionDate,
127
+ estimatedHoursRemaining,
128
+ windowHours,
129
+ dataPoints: debits.length,
130
+ };
131
+ }
132
+ }
133
+ exports.CreditLedger = CreditLedger;
134
+ //# sourceMappingURL=credit-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credit-ledger.js","sourceRoot":"","sources":["../src/credit-ledger.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -32,6 +32,8 @@ export type { OAuthClientRecord, OAuthTokenRecord, OAuthServerMetadata, OAuthCon
32
32
  export { SessionManager, writeSseHeaders, writeSseEvent, writeSseKeepAlive } from './session';
33
33
  export { AuditLogger, maskKeyForAudit } from './audit';
34
34
  export type { AuditEvent, AuditEventType, AuditLogConfig, AuditQuery, AuditQueryResult } from './audit';
35
+ export { CreditLedger } from './credit-ledger';
36
+ export type { CreditEntry, SpendingVelocity } from './credit-ledger';
35
37
  export { ToolRegistry } from './registry';
36
38
  export { MetricsCollector } from './metrics';
37
39
  export type { MetricLabels } from './metrics';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@
16
16
  * ```
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.DEFAULT_CONFIG = exports.KeyGroupManager = exports.PluginManager = exports.VALID_ROLES = exports.ROLE_HIERARCHY = exports.AdminKeyManager = exports.TokenRevocationList = exports.ScopedTokenManager = exports.formatDiagnostics = exports.validateConfig = exports.PayGateError = exports.PayGateClient = exports.RedisSync = exports.RedisSubscriber = exports.parseRedisUrl = exports.RedisClient = exports.TeamManager = exports.AlertEngine = exports.AnalyticsEngine = exports.getDashboardHtml = exports.MetricsCollector = exports.ToolRegistry = exports.maskKeyForAudit = exports.AuditLogger = exports.writeSseKeepAlive = exports.writeSseEvent = exports.writeSseHeaders = exports.SessionManager = exports.OAuthProvider = exports.QuotaTracker = exports.WebhookRouter = exports.WebhookEmitter = exports.StripeWebhookHandler = exports.RateLimiter = exports.UsageMeter = exports.KeyStore = exports.MultiServerRouter = exports.HttpMcpProxy = exports.McpProxy = exports.Gate = exports.resolveClientIp = exports.getRequestId = exports.generateRequestId = exports.PayGateServer = void 0;
19
+ exports.DEFAULT_CONFIG = exports.KeyGroupManager = exports.PluginManager = exports.VALID_ROLES = exports.ROLE_HIERARCHY = exports.AdminKeyManager = exports.TokenRevocationList = exports.ScopedTokenManager = exports.formatDiagnostics = exports.validateConfig = exports.PayGateError = exports.PayGateClient = exports.RedisSync = exports.RedisSubscriber = exports.parseRedisUrl = exports.RedisClient = exports.TeamManager = exports.AlertEngine = exports.AnalyticsEngine = exports.getDashboardHtml = exports.MetricsCollector = exports.ToolRegistry = exports.CreditLedger = exports.maskKeyForAudit = exports.AuditLogger = exports.writeSseKeepAlive = exports.writeSseEvent = exports.writeSseHeaders = exports.SessionManager = exports.OAuthProvider = exports.QuotaTracker = exports.WebhookRouter = exports.WebhookEmitter = exports.StripeWebhookHandler = exports.RateLimiter = exports.UsageMeter = exports.KeyStore = exports.MultiServerRouter = exports.HttpMcpProxy = exports.McpProxy = exports.Gate = exports.resolveClientIp = exports.getRequestId = exports.generateRequestId = exports.PayGateServer = void 0;
20
20
  var server_1 = require("./server");
21
21
  Object.defineProperty(exports, "PayGateServer", { enumerable: true, get: function () { return server_1.PayGateServer; } });
22
22
  Object.defineProperty(exports, "generateRequestId", { enumerable: true, get: function () { return server_1.generateRequestId; } });
@@ -54,6 +54,8 @@ Object.defineProperty(exports, "writeSseKeepAlive", { enumerable: true, get: fun
54
54
  var audit_1 = require("./audit");
55
55
  Object.defineProperty(exports, "AuditLogger", { enumerable: true, get: function () { return audit_1.AuditLogger; } });
56
56
  Object.defineProperty(exports, "maskKeyForAudit", { enumerable: true, get: function () { return audit_1.maskKeyForAudit; } });
57
+ var credit_ledger_1 = require("./credit-ledger");
58
+ Object.defineProperty(exports, "CreditLedger", { enumerable: true, get: function () { return credit_ledger_1.CreditLedger; } });
57
59
  var registry_1 = require("./registry");
58
60
  Object.defineProperty(exports, "ToolRegistry", { enumerable: true, get: function () { return registry_1.ToolRegistry; } });
59
61
  var metrics_1 = require("./metrics");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,mCAA2F;AAAlF,uGAAA,aAAa,OAAA;AAAE,2GAAA,iBAAiB,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,yGAAA,eAAe,OAAA;AACxE,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,iCAAmC;AAA1B,iGAAA,QAAQ,OAAA;AACjB,2CAA4C;AAAnC,0GAAA,YAAY,OAAA;AACrB,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAC1B,iCAAmC;AAA1B,iGAAA,QAAQ,OAAA;AACjB,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AACnB,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,mCAAgD;AAAvC,8GAAA,oBAAoB,OAAA;AAC7B,qCAA2C;AAAlC,yGAAA,cAAc,OAAA;AAEvB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,iCAAuC;AAA9B,qGAAA,YAAY,OAAA;AACrB,iCAAwC;AAA/B,sGAAA,aAAa,OAAA;AAEtB,qCAA8F;AAArF,yGAAA,cAAc,OAAA;AAAE,0GAAA,eAAe,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,4GAAA,iBAAiB,OAAA;AAC1E,iCAAuD;AAA9C,oGAAA,WAAW,OAAA;AAAE,wGAAA,eAAe,OAAA;AAErC,uCAA0C;AAAjC,wGAAA,YAAY,OAAA;AACrB,qCAA6C;AAApC,2GAAA,gBAAgB,OAAA;AAIzB,yCAA+C;AAAtC,6GAAA,gBAAgB,OAAA;AACzB,yCAA8C;AAArC,4GAAA,eAAe,OAAA;AAExB,mCAAuC;AAA9B,qGAAA,WAAW,OAAA;AAEpB,iCAAsC;AAA7B,oGAAA,WAAW,OAAA;AAEpB,+CAA6E;AAApE,2GAAA,WAAW,OAAA;AAAE,6GAAA,aAAa,OAAA;AAAE,+GAAA,eAAe,OAAA;AAEpD,2CAAyC;AAAhC,uGAAA,SAAS,OAAA;AAElB,mCAAuD;AAA9C,uGAAA,aAAa,OAAA;AAAE,sGAAA,YAAY,OAAA;AAEpC,uDAAuE;AAA9D,kHAAA,cAAc,OAAA;AAAE,qHAAA,iBAAiB,OAAA;AAE1C,mCAAmE;AAA1D,4GAAA,kBAAkB,OAAA;AAAE,6GAAA,mBAAmB,OAAA;AAEhD,2CAA4E;AAAnE,6GAAA,eAAe,OAAA;AAAE,4GAAA,cAAc,OAAA;AAAE,yGAAA,WAAW,OAAA;AAErD,mCAAyC;AAAhC,uGAAA,aAAa,OAAA;AAEtB,mCAA2C;AAAlC,yGAAA,eAAe,OAAA;AAwBxB,iCAAyC;AAAhC,uGAAA,cAAc,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,mCAA2F;AAAlF,uGAAA,aAAa,OAAA;AAAE,2GAAA,iBAAiB,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,yGAAA,eAAe,OAAA;AACxE,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,iCAAmC;AAA1B,iGAAA,QAAQ,OAAA;AACjB,2CAA4C;AAAnC,0GAAA,YAAY,OAAA;AACrB,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAC1B,iCAAmC;AAA1B,iGAAA,QAAQ,OAAA;AACjB,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AACnB,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,mCAAgD;AAAvC,8GAAA,oBAAoB,OAAA;AAC7B,qCAA2C;AAAlC,yGAAA,cAAc,OAAA;AAEvB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,iCAAuC;AAA9B,qGAAA,YAAY,OAAA;AACrB,iCAAwC;AAA/B,sGAAA,aAAa,OAAA;AAEtB,qCAA8F;AAArF,yGAAA,cAAc,OAAA;AAAE,0GAAA,eAAe,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,4GAAA,iBAAiB,OAAA;AAC1E,iCAAuD;AAA9C,oGAAA,WAAW,OAAA;AAAE,wGAAA,eAAe,OAAA;AAErC,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AAErB,uCAA0C;AAAjC,wGAAA,YAAY,OAAA;AACrB,qCAA6C;AAApC,2GAAA,gBAAgB,OAAA;AAIzB,yCAA+C;AAAtC,6GAAA,gBAAgB,OAAA;AACzB,yCAA8C;AAArC,4GAAA,eAAe,OAAA;AAExB,mCAAuC;AAA9B,qGAAA,WAAW,OAAA;AAEpB,iCAAsC;AAA7B,oGAAA,WAAW,OAAA;AAEpB,+CAA6E;AAApE,2GAAA,WAAW,OAAA;AAAE,6GAAA,aAAa,OAAA;AAAE,+GAAA,eAAe,OAAA;AAEpD,2CAAyC;AAAhC,uGAAA,SAAS,OAAA;AAElB,mCAAuD;AAA9C,uGAAA,aAAa,OAAA;AAAE,sGAAA,YAAY,OAAA;AAEpC,uDAAuE;AAA9D,kHAAA,cAAc,OAAA;AAAE,qHAAA,iBAAiB,OAAA;AAE1C,mCAAmE;AAA1D,4GAAA,kBAAkB,OAAA;AAAE,6GAAA,mBAAmB,OAAA;AAEhD,2CAA4E;AAAnE,6GAAA,eAAe,OAAA;AAAE,4GAAA,cAAc,OAAA;AAAE,yGAAA,WAAW,OAAA;AAErD,mCAAyC;AAAhC,uGAAA,aAAa,OAAA;AAEtB,mCAA2C;AAAlC,yGAAA,eAAe,OAAA;AAwBxB,iCAAyC;AAAhC,uGAAA,cAAc,OAAA"}
package/dist/server.d.ts CHANGED
@@ -21,6 +21,7 @@ import { MultiServerRouter } from './router';
21
21
  import { OAuthProvider } from './oauth';
22
22
  import { SessionManager } from './session';
23
23
  import { AuditLogger } from './audit';
24
+ import { CreditLedger } from './credit-ledger';
24
25
  import { ToolRegistry } from './registry';
25
26
  import { MetricsCollector } from './metrics';
26
27
  import { AnalyticsEngine } from './analytics';
@@ -90,6 +91,8 @@ export declare class PayGateServer {
90
91
  readonly expiryScanner: ExpiryScanner;
91
92
  /** Key template manager for reusable key presets */
92
93
  readonly templates: KeyTemplateManager;
94
+ /** Per-key credit mutation history */
95
+ readonly creditLedger: CreditLedger;
93
96
  /** Server start time (ms since epoch) */
94
97
  private readonly startedAt;
95
98
  /** Whether the server is draining (shutting down gracefully) */
@@ -178,6 +181,8 @@ export declare class PayGateServer {
178
181
  private handleKeyStats;
179
182
  private handleRateLimitStatus;
180
183
  private handleQuotaStatus;
184
+ private handleCreditHistory;
185
+ private handleSpendingVelocity;
181
186
  private handleSetAutoTopup;
182
187
  private handleBalance;
183
188
  private handleLimits;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -75,6 +75,7 @@ const stripe_1 = require("./stripe");
75
75
  const oauth_1 = require("./oauth");
76
76
  const session_1 = require("./session");
77
77
  const audit_1 = require("./audit");
78
+ const credit_ledger_1 = require("./credit-ledger");
78
79
  const registry_1 = require("./registry");
79
80
  const metrics_1 = require("./metrics");
80
81
  const dashboard_1 = require("./dashboard");
@@ -208,6 +209,8 @@ class PayGateServer {
208
209
  expiryScanner;
209
210
  /** Key template manager for reusable key presets */
210
211
  templates;
212
+ /** Per-key credit mutation history */
213
+ creditLedger;
211
214
  /** Server start time (ms since epoch) */
212
215
  startedAt = Date.now();
213
216
  /** Whether the server is draining (shutting down gracefully) */
@@ -303,6 +306,9 @@ class PayGateServer {
303
306
  // Wire auto-topup hook: audit log + webhook + Redis sync
304
307
  this.gate.onAutoTopup = (apiKey, amount, newBalance) => {
305
308
  const keyMasked = (0, audit_1.maskKeyForAudit)(apiKey);
309
+ this.creditLedger.record(apiKey, {
310
+ type: 'auto_topup', amount, balanceBefore: newBalance - amount, balanceAfter: newBalance,
311
+ });
306
312
  this.audit.log('key.auto_topped_up', 'system', `Auto-topup: added ${amount} credits`, {
307
313
  keyMasked, creditsAdded: amount, newBalance,
308
314
  });
@@ -347,6 +353,7 @@ class PayGateServer {
347
353
  // Key template manager for reusable key creation presets
348
354
  const templatesStatePath = statePath ? statePath.replace(/\.json$/, '-templates.json') : undefined;
349
355
  this.templates = new key_templates_1.KeyTemplateManager(templatesStatePath);
356
+ this.creditLedger = new credit_ledger_1.CreditLedger();
350
357
  this.metrics.registerGauge('paygate_templates_total', 'Number of key templates', () => {
351
358
  return this.templates.count;
352
359
  });
@@ -529,6 +536,10 @@ class PayGateServer {
529
536
  return this.handleRateLimitStatus(req, res);
530
537
  case '/keys/quota-status':
531
538
  return this.handleQuotaStatus(req, res);
539
+ case '/keys/credit-history':
540
+ return this.handleCreditHistory(req, res);
541
+ case '/keys/spending-velocity':
542
+ return this.handleSpendingVelocity(req, res);
532
543
  case '/keys/templates':
533
544
  if (req.method === 'GET')
534
545
  return this.handleListTemplates(req, res);
@@ -1074,6 +1085,8 @@ class PayGateServer {
1074
1085
  keyStats: 'GET /keys/stats — Aggregate key statistics (requires X-Admin-Key)',
1075
1086
  rateLimitStatus: 'GET /keys/rate-limit-status?key=... — Current rate limit window state (requires X-Admin-Key)',
1076
1087
  quotaStatus: 'GET /keys/quota-status?key=... — Current daily/monthly quota usage (requires X-Admin-Key)',
1088
+ creditHistory: 'GET /keys/credit-history?key=... — Per-key credit mutation history (requires X-Admin-Key)',
1089
+ spendingVelocity: 'GET /keys/spending-velocity?key=... — Spending rate and depletion forecast (requires X-Admin-Key)',
1077
1090
  keyTemplates: 'GET /keys/templates — List key templates + POST to create/update (requires X-Admin-Key)',
1078
1091
  deleteTemplate: 'POST /keys/templates/delete — Delete a key template (requires X-Admin-Key)',
1079
1092
  pricing: 'GET /pricing — Tool pricing breakdown (public)',
@@ -1381,6 +1394,9 @@ class PayGateServer {
1381
1394
  this.redisSync.saveKey(record).catch(() => { });
1382
1395
  this.redisSync.publishEvent({ type: 'key_created', key: record.key }).catch(() => { });
1383
1396
  }
1397
+ this.creditLedger.record(record.key, {
1398
+ type: 'initial', amount: credits, balanceBefore: 0, balanceAfter: credits,
1399
+ });
1384
1400
  this.audit.log('key.created', 'admin', `Key created: ${name}`, {
1385
1401
  keyMasked: (0, audit_1.maskKeyForAudit)(record.key),
1386
1402
  name,
@@ -1476,6 +1492,7 @@ class PayGateServer {
1476
1492
  // Resolve alias to actual key
1477
1493
  const resolved = this.gate.store.resolveKey(params.key);
1478
1494
  const actualKey = resolved ? resolved.key : params.key;
1495
+ const balanceBefore = this.gate.store.getKey(actualKey)?.credits ?? 0;
1479
1496
  // Use Redis atomic topup when available, fall back to local store
1480
1497
  let success;
1481
1498
  if (this.redisSync) {
@@ -1490,6 +1507,9 @@ class PayGateServer {
1490
1507
  return;
1491
1508
  }
1492
1509
  const record = this.gate.store.getKey(actualKey);
1510
+ this.creditLedger.record(actualKey, {
1511
+ type: 'topup', amount: credits, balanceBefore, balanceAfter: record?.credits ?? balanceBefore + credits,
1512
+ });
1493
1513
  this.audit.log('key.topup', 'admin', `Added ${credits} credits`, {
1494
1514
  keyMasked: (0, audit_1.maskKeyForAudit)(params.key),
1495
1515
  creditsAdded: credits,
@@ -1557,6 +1577,8 @@ class PayGateServer {
1557
1577
  res.end(JSON.stringify({ error: 'Destination key not found' }));
1558
1578
  return;
1559
1579
  }
1580
+ const sourceBalanceBefore = sourceRecord.credits;
1581
+ const destBalanceBefore = destRecord.credits;
1560
1582
  // Perform transfer atomically (deduct from source, add to destination)
1561
1583
  if (this.redisSync) {
1562
1584
  // Redis atomic transfer: deduct first, then add
@@ -1577,6 +1599,12 @@ class PayGateServer {
1577
1599
  const fromBalance = sourceRecord.credits;
1578
1600
  const toBalance = destRecord.credits;
1579
1601
  const memo = params.memo || '';
1602
+ this.creditLedger.record(sourceRecord.key, {
1603
+ type: 'transfer_out', amount: credits, balanceBefore: sourceBalanceBefore, balanceAfter: fromBalance, memo: memo || undefined,
1604
+ });
1605
+ this.creditLedger.record(destRecord.key, {
1606
+ type: 'transfer_in', amount: credits, balanceBefore: destBalanceBefore, balanceAfter: toBalance, memo: memo || undefined,
1607
+ });
1580
1608
  this.audit.log('key.credits_transferred', 'admin', `Transferred ${credits} credits`, {
1581
1609
  fromKeyMasked: (0, audit_1.maskKeyForAudit)(sourceRecord.key),
1582
1610
  toKeyMasked: (0, audit_1.maskKeyForAudit)(destRecord.key),
@@ -2714,6 +2742,93 @@ class PayGateServer {
2714
2742
  monthly,
2715
2743
  }));
2716
2744
  }
2745
+ // ─── /keys/credit-history — Per-key credit mutation history ──────────────────
2746
+ handleCreditHistory(req, res) {
2747
+ if (req.method !== 'GET') {
2748
+ res.writeHead(405, { 'Content-Type': 'application/json' });
2749
+ res.end(JSON.stringify({ error: 'Method not allowed' }));
2750
+ return;
2751
+ }
2752
+ if (!this.checkAdmin(req, res))
2753
+ return;
2754
+ const urlParts = req.url?.split('?') || [];
2755
+ const params = new URLSearchParams(urlParts[1] || '');
2756
+ const key = params.get('key');
2757
+ if (!key) {
2758
+ res.writeHead(400, { 'Content-Type': 'application/json' });
2759
+ res.end(JSON.stringify({ error: 'Missing required query parameter: key' }));
2760
+ return;
2761
+ }
2762
+ // Resolve alias
2763
+ const resolved = this.gate.store.resolveKey(key);
2764
+ const actualKey = resolved ? resolved.key : key;
2765
+ const keyRecord = this.gate.store.getKey(actualKey);
2766
+ if (!keyRecord) {
2767
+ res.writeHead(404, { 'Content-Type': 'application/json' });
2768
+ res.end(JSON.stringify({ error: 'Key not found' }));
2769
+ return;
2770
+ }
2771
+ const type = params.get('type') || undefined;
2772
+ const limit = Math.min(Math.max(1, Number(params.get('limit')) || 50), 200);
2773
+ const since = params.get('since') || undefined;
2774
+ const entries = this.creditLedger.getHistory(actualKey, { type, limit, since });
2775
+ res.writeHead(200, { 'Content-Type': 'application/json' });
2776
+ res.end(JSON.stringify({
2777
+ key: actualKey.slice(0, 10) + '...',
2778
+ name: keyRecord.name,
2779
+ currentBalance: keyRecord.credits,
2780
+ totalEntries: this.creditLedger.count(actualKey),
2781
+ entries,
2782
+ }));
2783
+ }
2784
+ // ─── /keys/spending-velocity — Spending rate + depletion forecast ────────────
2785
+ handleSpendingVelocity(req, res) {
2786
+ if (req.method !== 'GET') {
2787
+ res.writeHead(405, { 'Content-Type': 'application/json' });
2788
+ res.end(JSON.stringify({ error: 'Method not allowed' }));
2789
+ return;
2790
+ }
2791
+ if (!this.checkAdmin(req, res))
2792
+ return;
2793
+ const urlParts = req.url?.split('?') || [];
2794
+ const params = new URLSearchParams(urlParts[1] || '');
2795
+ const key = params.get('key');
2796
+ if (!key) {
2797
+ res.writeHead(400, { 'Content-Type': 'application/json' });
2798
+ res.end(JSON.stringify({ error: 'Missing required query parameter: key' }));
2799
+ return;
2800
+ }
2801
+ // Resolve alias
2802
+ const resolved = this.gate.store.resolveKey(key);
2803
+ const actualKey = resolved ? resolved.key : key;
2804
+ const keyRecord = this.gate.store.getKey(actualKey);
2805
+ if (!keyRecord) {
2806
+ res.writeHead(404, { 'Content-Type': 'application/json' });
2807
+ res.end(JSON.stringify({ error: 'Key not found' }));
2808
+ return;
2809
+ }
2810
+ const windowParam = params.get('window');
2811
+ const windowHours = Math.min(Math.max(1, windowParam !== null ? (Number(windowParam) || 1) : 24), 720); // 1h to 30 days
2812
+ const velocity = this.creditLedger.getSpendingVelocity(actualKey, keyRecord.credits, windowHours);
2813
+ // Get top tools from usage meter (per-key usage)
2814
+ const keyUsage = this.gate.meter.getKeyUsage(actualKey);
2815
+ const topTools = [];
2816
+ if (keyUsage && keyUsage.perTool) {
2817
+ const toolEntries = Object.entries(keyUsage.perTool)
2818
+ .map(([tool, stats]) => ({ tool, calls: stats.calls, credits: stats.credits }))
2819
+ .sort((a, b) => b.credits - a.credits)
2820
+ .slice(0, 5);
2821
+ topTools.push(...toolEntries);
2822
+ }
2823
+ res.writeHead(200, { 'Content-Type': 'application/json' });
2824
+ res.end(JSON.stringify({
2825
+ key: actualKey.slice(0, 10) + '...',
2826
+ name: keyRecord.name,
2827
+ currentBalance: keyRecord.credits,
2828
+ velocity,
2829
+ topTools,
2830
+ }));
2831
+ }
2717
2832
  // ─── /keys/auto-topup — Configure auto-topup ────────────────────────────────
2718
2833
  async handleSetAutoTopup(req, res) {
2719
2834
  if (req.method !== 'POST') {