paygate-mcp 6.2.0 → 6.4.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 +80 -0
- package/dist/credit-ledger.d.ts +42 -0
- package/dist/credit-ledger.d.ts.map +1 -0
- package/dist/credit-ledger.js +67 -0
- package/dist/credit-ledger.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +129 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -89,6 +89,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
89
89
|
- **Key Listing Pagination** — Enhanced `GET /keys` with cursor-based pagination (`limit`/`offset`), sorting (`sortBy`/`order`), and filtering by namespace, group, active/suspended/expired status, name prefix, and credit range — backward compatible (returns flat array when no pagination params used)
|
|
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
|
+
- **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
|
|
92
94
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
93
95
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
94
96
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -1678,6 +1680,84 @@ curl "http://localhost:3402/keys/rate-limit-status?key=pg_..." -H "X-Admin-Key:
|
|
|
1678
1680
|
|
|
1679
1681
|
`perTool` is only present when tools have per-tool rate limits configured via `toolPricing`. Tools without custom rate limits are not included.
|
|
1680
1682
|
|
|
1683
|
+
### Quota Status
|
|
1684
|
+
|
|
1685
|
+
`GET /keys/quota-status?key=...` returns daily/monthly quota usage for a key:
|
|
1686
|
+
|
|
1687
|
+
```bash
|
|
1688
|
+
curl "http://localhost:3402/keys/quota-status?key=pg_..." -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
1689
|
+
```
|
|
1690
|
+
|
|
1691
|
+
**Response:**
|
|
1692
|
+
|
|
1693
|
+
```json
|
|
1694
|
+
{
|
|
1695
|
+
"key": "pg_abc123...",
|
|
1696
|
+
"name": "my-key",
|
|
1697
|
+
"quotaSource": "global",
|
|
1698
|
+
"daily": {
|
|
1699
|
+
"callsUsed": 42,
|
|
1700
|
+
"callsLimit": 100,
|
|
1701
|
+
"callsRemaining": 58,
|
|
1702
|
+
"creditsUsed": 150,
|
|
1703
|
+
"creditsLimit": 500,
|
|
1704
|
+
"creditsRemaining": 350,
|
|
1705
|
+
"resetDay": "2026-02-26"
|
|
1706
|
+
},
|
|
1707
|
+
"monthly": {
|
|
1708
|
+
"callsUsed": 850,
|
|
1709
|
+
"callsLimit": 2000,
|
|
1710
|
+
"callsRemaining": 1150,
|
|
1711
|
+
"creditsUsed": 3200,
|
|
1712
|
+
"creditsLimit": 10000,
|
|
1713
|
+
"creditsRemaining": 6800,
|
|
1714
|
+
"resetMonth": "2026-02"
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
```
|
|
1718
|
+
|
|
1719
|
+
`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`.
|
|
1720
|
+
|
|
1721
|
+
### Credit History
|
|
1722
|
+
|
|
1723
|
+
`GET /keys/credit-history?key=...` returns the credit mutation log for a key:
|
|
1724
|
+
|
|
1725
|
+
```bash
|
|
1726
|
+
curl "http://localhost:3402/keys/credit-history?key=pg_..." -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
1727
|
+
|
|
1728
|
+
# Filter by type, limit, or since timestamp
|
|
1729
|
+
curl "http://localhost:3402/keys/credit-history?key=pg_...&type=topup&limit=10" -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
1730
|
+
```
|
|
1731
|
+
|
|
1732
|
+
**Response:**
|
|
1733
|
+
|
|
1734
|
+
```json
|
|
1735
|
+
{
|
|
1736
|
+
"key": "pg_abc123...",
|
|
1737
|
+
"name": "my-key",
|
|
1738
|
+
"currentBalance": 700,
|
|
1739
|
+
"totalEntries": 3,
|
|
1740
|
+
"entries": [
|
|
1741
|
+
{
|
|
1742
|
+
"timestamp": "2026-02-26T12:30:00.000Z",
|
|
1743
|
+
"type": "topup",
|
|
1744
|
+
"amount": 200,
|
|
1745
|
+
"balanceBefore": 500,
|
|
1746
|
+
"balanceAfter": 700
|
|
1747
|
+
},
|
|
1748
|
+
{
|
|
1749
|
+
"timestamp": "2026-02-26T12:00:00.000Z",
|
|
1750
|
+
"type": "initial",
|
|
1751
|
+
"amount": 500,
|
|
1752
|
+
"balanceBefore": 0,
|
|
1753
|
+
"balanceAfter": 500
|
|
1754
|
+
}
|
|
1755
|
+
]
|
|
1756
|
+
}
|
|
1757
|
+
```
|
|
1758
|
+
|
|
1759
|
+
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.
|
|
1760
|
+
|
|
1681
1761
|
### IP Allowlisting
|
|
1682
1762
|
|
|
1683
1763
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
//# 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;CAGzB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
exports.CreditLedger = CreditLedger;
|
|
67
|
+
//# sourceMappingURL=credit-ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credit-ledger.js","sourceRoot":"","sources":["../src/credit-ledger.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAYH,MAAa,YAAY;IACf,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC3C,gBAAgB,CAAS;IAEjC,YAAY,gBAAgB,GAAG,GAAG;QAChC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,GAAW,EAAE,KAAqC;QACvD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5B,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC;YACR,GAAG,KAAK;YACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QACH,qBAAqB;QACrB,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,GAAW,EAAE,IAAwD;QAC9E,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAE1C,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,eAAe;QAEjD,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC;YACf,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;YAChB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,KAAM,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAW;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAW;QACf,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF;AA9DD,oCA8DC"}
|
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 } from './credit-ledger';
|
|
35
37
|
export { ToolRegistry } from './registry';
|
|
36
38
|
export { MetricsCollector } from './metrics';
|
|
37
39
|
export type { MetricLabels } from './metrics';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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) */
|
|
@@ -177,6 +180,8 @@ export declare class PayGateServer {
|
|
|
177
180
|
private handleKeysExpiring;
|
|
178
181
|
private handleKeyStats;
|
|
179
182
|
private handleRateLimitStatus;
|
|
183
|
+
private handleQuotaStatus;
|
|
184
|
+
private handleCreditHistory;
|
|
180
185
|
private handleSetAutoTopup;
|
|
181
186
|
private handleBalance;
|
|
182
187
|
private handleLimits;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -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
|
});
|
|
@@ -527,6 +534,10 @@ class PayGateServer {
|
|
|
527
534
|
return this.handleKeyStats(req, res);
|
|
528
535
|
case '/keys/rate-limit-status':
|
|
529
536
|
return this.handleRateLimitStatus(req, res);
|
|
537
|
+
case '/keys/quota-status':
|
|
538
|
+
return this.handleQuotaStatus(req, res);
|
|
539
|
+
case '/keys/credit-history':
|
|
540
|
+
return this.handleCreditHistory(req, res);
|
|
530
541
|
case '/keys/templates':
|
|
531
542
|
if (req.method === 'GET')
|
|
532
543
|
return this.handleListTemplates(req, res);
|
|
@@ -1071,6 +1082,8 @@ class PayGateServer {
|
|
|
1071
1082
|
keysExpiring: 'GET /keys/expiring?within=86400 — List keys expiring within N seconds (requires X-Admin-Key)',
|
|
1072
1083
|
keyStats: 'GET /keys/stats — Aggregate key statistics (requires X-Admin-Key)',
|
|
1073
1084
|
rateLimitStatus: 'GET /keys/rate-limit-status?key=... — Current rate limit window state (requires X-Admin-Key)',
|
|
1085
|
+
quotaStatus: 'GET /keys/quota-status?key=... — Current daily/monthly quota usage (requires X-Admin-Key)',
|
|
1086
|
+
creditHistory: 'GET /keys/credit-history?key=... — Per-key credit mutation history (requires X-Admin-Key)',
|
|
1074
1087
|
keyTemplates: 'GET /keys/templates — List key templates + POST to create/update (requires X-Admin-Key)',
|
|
1075
1088
|
deleteTemplate: 'POST /keys/templates/delete — Delete a key template (requires X-Admin-Key)',
|
|
1076
1089
|
pricing: 'GET /pricing — Tool pricing breakdown (public)',
|
|
@@ -1378,6 +1391,9 @@ class PayGateServer {
|
|
|
1378
1391
|
this.redisSync.saveKey(record).catch(() => { });
|
|
1379
1392
|
this.redisSync.publishEvent({ type: 'key_created', key: record.key }).catch(() => { });
|
|
1380
1393
|
}
|
|
1394
|
+
this.creditLedger.record(record.key, {
|
|
1395
|
+
type: 'initial', amount: credits, balanceBefore: 0, balanceAfter: credits,
|
|
1396
|
+
});
|
|
1381
1397
|
this.audit.log('key.created', 'admin', `Key created: ${name}`, {
|
|
1382
1398
|
keyMasked: (0, audit_1.maskKeyForAudit)(record.key),
|
|
1383
1399
|
name,
|
|
@@ -1473,6 +1489,7 @@ class PayGateServer {
|
|
|
1473
1489
|
// Resolve alias to actual key
|
|
1474
1490
|
const resolved = this.gate.store.resolveKey(params.key);
|
|
1475
1491
|
const actualKey = resolved ? resolved.key : params.key;
|
|
1492
|
+
const balanceBefore = this.gate.store.getKey(actualKey)?.credits ?? 0;
|
|
1476
1493
|
// Use Redis atomic topup when available, fall back to local store
|
|
1477
1494
|
let success;
|
|
1478
1495
|
if (this.redisSync) {
|
|
@@ -1487,6 +1504,9 @@ class PayGateServer {
|
|
|
1487
1504
|
return;
|
|
1488
1505
|
}
|
|
1489
1506
|
const record = this.gate.store.getKey(actualKey);
|
|
1507
|
+
this.creditLedger.record(actualKey, {
|
|
1508
|
+
type: 'topup', amount: credits, balanceBefore, balanceAfter: record?.credits ?? balanceBefore + credits,
|
|
1509
|
+
});
|
|
1490
1510
|
this.audit.log('key.topup', 'admin', `Added ${credits} credits`, {
|
|
1491
1511
|
keyMasked: (0, audit_1.maskKeyForAudit)(params.key),
|
|
1492
1512
|
creditsAdded: credits,
|
|
@@ -1554,6 +1574,8 @@ class PayGateServer {
|
|
|
1554
1574
|
res.end(JSON.stringify({ error: 'Destination key not found' }));
|
|
1555
1575
|
return;
|
|
1556
1576
|
}
|
|
1577
|
+
const sourceBalanceBefore = sourceRecord.credits;
|
|
1578
|
+
const destBalanceBefore = destRecord.credits;
|
|
1557
1579
|
// Perform transfer atomically (deduct from source, add to destination)
|
|
1558
1580
|
if (this.redisSync) {
|
|
1559
1581
|
// Redis atomic transfer: deduct first, then add
|
|
@@ -1574,6 +1596,12 @@ class PayGateServer {
|
|
|
1574
1596
|
const fromBalance = sourceRecord.credits;
|
|
1575
1597
|
const toBalance = destRecord.credits;
|
|
1576
1598
|
const memo = params.memo || '';
|
|
1599
|
+
this.creditLedger.record(sourceRecord.key, {
|
|
1600
|
+
type: 'transfer_out', amount: credits, balanceBefore: sourceBalanceBefore, balanceAfter: fromBalance, memo: memo || undefined,
|
|
1601
|
+
});
|
|
1602
|
+
this.creditLedger.record(destRecord.key, {
|
|
1603
|
+
type: 'transfer_in', amount: credits, balanceBefore: destBalanceBefore, balanceAfter: toBalance, memo: memo || undefined,
|
|
1604
|
+
});
|
|
1577
1605
|
this.audit.log('key.credits_transferred', 'admin', `Transferred ${credits} credits`, {
|
|
1578
1606
|
fromKeyMasked: (0, audit_1.maskKeyForAudit)(sourceRecord.key),
|
|
1579
1607
|
toKeyMasked: (0, audit_1.maskKeyForAudit)(destRecord.key),
|
|
@@ -2649,6 +2677,107 @@ class PayGateServer {
|
|
|
2649
2677
|
perTool: Object.keys(perTool).length > 0 ? perTool : undefined,
|
|
2650
2678
|
}));
|
|
2651
2679
|
}
|
|
2680
|
+
// ─── /keys/quota-status — Current daily/monthly quota usage ──────────────────
|
|
2681
|
+
handleQuotaStatus(req, res) {
|
|
2682
|
+
if (req.method !== 'GET') {
|
|
2683
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
2684
|
+
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
2685
|
+
return;
|
|
2686
|
+
}
|
|
2687
|
+
if (!this.checkAdmin(req, res))
|
|
2688
|
+
return;
|
|
2689
|
+
const urlParts = req.url?.split('?') || [];
|
|
2690
|
+
const params = new URLSearchParams(urlParts[1] || '');
|
|
2691
|
+
const key = params.get('key');
|
|
2692
|
+
if (!key) {
|
|
2693
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
2694
|
+
res.end(JSON.stringify({ error: 'Missing required query parameter: key' }));
|
|
2695
|
+
return;
|
|
2696
|
+
}
|
|
2697
|
+
const keyRecord = this.gate.store.getKey(key);
|
|
2698
|
+
if (!keyRecord) {
|
|
2699
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
2700
|
+
res.end(JSON.stringify({ error: 'Key not found' }));
|
|
2701
|
+
return;
|
|
2702
|
+
}
|
|
2703
|
+
// Ensure counters are reset if day/month rolled over
|
|
2704
|
+
this.gate.quotaTracker.resetIfNeeded(keyRecord);
|
|
2705
|
+
// Resolve effective quota: per-key overrides global
|
|
2706
|
+
const effectiveQuota = keyRecord.quota || this.config.globalQuota;
|
|
2707
|
+
const daily = {
|
|
2708
|
+
callsUsed: keyRecord.quotaDailyCalls,
|
|
2709
|
+
callsLimit: effectiveQuota?.dailyCallLimit || 0,
|
|
2710
|
+
callsRemaining: effectiveQuota?.dailyCallLimit
|
|
2711
|
+
? Math.max(0, effectiveQuota.dailyCallLimit - keyRecord.quotaDailyCalls)
|
|
2712
|
+
: null,
|
|
2713
|
+
creditsUsed: keyRecord.quotaDailyCredits,
|
|
2714
|
+
creditsLimit: effectiveQuota?.dailyCreditLimit || 0,
|
|
2715
|
+
creditsRemaining: effectiveQuota?.dailyCreditLimit
|
|
2716
|
+
? Math.max(0, effectiveQuota.dailyCreditLimit - keyRecord.quotaDailyCredits)
|
|
2717
|
+
: null,
|
|
2718
|
+
resetDay: keyRecord.quotaLastResetDay,
|
|
2719
|
+
};
|
|
2720
|
+
const monthly = {
|
|
2721
|
+
callsUsed: keyRecord.quotaMonthlyCalls,
|
|
2722
|
+
callsLimit: effectiveQuota?.monthlyCallLimit || 0,
|
|
2723
|
+
callsRemaining: effectiveQuota?.monthlyCallLimit
|
|
2724
|
+
? Math.max(0, effectiveQuota.monthlyCallLimit - keyRecord.quotaMonthlyCalls)
|
|
2725
|
+
: null,
|
|
2726
|
+
creditsUsed: keyRecord.quotaMonthlyCredits,
|
|
2727
|
+
creditsLimit: effectiveQuota?.monthlyCreditLimit || 0,
|
|
2728
|
+
creditsRemaining: effectiveQuota?.monthlyCreditLimit
|
|
2729
|
+
? Math.max(0, effectiveQuota.monthlyCreditLimit - keyRecord.quotaMonthlyCredits)
|
|
2730
|
+
: null,
|
|
2731
|
+
resetMonth: keyRecord.quotaLastResetMonth,
|
|
2732
|
+
};
|
|
2733
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
2734
|
+
res.end(JSON.stringify({
|
|
2735
|
+
key: key.slice(0, 10) + '...',
|
|
2736
|
+
name: keyRecord.name,
|
|
2737
|
+
quotaSource: keyRecord.quota ? 'per-key' : (this.config.globalQuota ? 'global' : 'none'),
|
|
2738
|
+
daily,
|
|
2739
|
+
monthly,
|
|
2740
|
+
}));
|
|
2741
|
+
}
|
|
2742
|
+
// ─── /keys/credit-history — Per-key credit mutation history ──────────────────
|
|
2743
|
+
handleCreditHistory(req, res) {
|
|
2744
|
+
if (req.method !== 'GET') {
|
|
2745
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
2746
|
+
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
2747
|
+
return;
|
|
2748
|
+
}
|
|
2749
|
+
if (!this.checkAdmin(req, res))
|
|
2750
|
+
return;
|
|
2751
|
+
const urlParts = req.url?.split('?') || [];
|
|
2752
|
+
const params = new URLSearchParams(urlParts[1] || '');
|
|
2753
|
+
const key = params.get('key');
|
|
2754
|
+
if (!key) {
|
|
2755
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
2756
|
+
res.end(JSON.stringify({ error: 'Missing required query parameter: key' }));
|
|
2757
|
+
return;
|
|
2758
|
+
}
|
|
2759
|
+
// Resolve alias
|
|
2760
|
+
const resolved = this.gate.store.resolveKey(key);
|
|
2761
|
+
const actualKey = resolved ? resolved.key : key;
|
|
2762
|
+
const keyRecord = this.gate.store.getKey(actualKey);
|
|
2763
|
+
if (!keyRecord) {
|
|
2764
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
2765
|
+
res.end(JSON.stringify({ error: 'Key not found' }));
|
|
2766
|
+
return;
|
|
2767
|
+
}
|
|
2768
|
+
const type = params.get('type') || undefined;
|
|
2769
|
+
const limit = Math.min(Math.max(1, Number(params.get('limit')) || 50), 200);
|
|
2770
|
+
const since = params.get('since') || undefined;
|
|
2771
|
+
const entries = this.creditLedger.getHistory(actualKey, { type, limit, since });
|
|
2772
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
2773
|
+
res.end(JSON.stringify({
|
|
2774
|
+
key: actualKey.slice(0, 10) + '...',
|
|
2775
|
+
name: keyRecord.name,
|
|
2776
|
+
currentBalance: keyRecord.credits,
|
|
2777
|
+
totalEntries: this.creditLedger.count(actualKey),
|
|
2778
|
+
entries,
|
|
2779
|
+
}));
|
|
2780
|
+
}
|
|
2652
2781
|
// ─── /keys/auto-topup — Configure auto-topup ────────────────────────────────
|
|
2653
2782
|
async handleSetAutoTopup(req, res) {
|
|
2654
2783
|
if (req.method !== 'POST') {
|