@apicity/cost 0.2.0-alpha.0 → 0.2.0-alpha.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/README.md CHANGED
@@ -142,6 +142,264 @@ Maintenance is manual: re-fetch each upstream's pricing page, edit `pricing.ts`,
142
142
  | `kie` | `per-unit-table` | priced per second of video / per image |
143
143
  | `free` | `free` | always $0 |
144
144
 
145
+ ## Paid endpoint guard (OTP pay gate)
146
+
147
+ Some endpoints have a direct marginal compute cost (e.g. video generation).
148
+ The cost package maintains a small, explicit **paid-endpoint registry**.
149
+ Endpoints that are **not** in the registry are assumed free and require no
150
+ caller changes.
151
+
152
+ Paid endpoints require a **human-minted, single-request OTP** (one-time
153
+ password). Autonomous callers cannot self-approve paid requests by passing
154
+ a numeric `maxSpend` — they must present an OTP that was signed by an
155
+ operator-held Ed25519 key.
156
+
157
+ ### Registry model
158
+
159
+ - `PAID_ENDPOINTS` is the canonical list. Every entry is an exact triple of
160
+ `(provider, method, dotPath)` — there is no regex, prefix, wildcard, or
161
+ inferred matching.
162
+ - Unlisted endpoints are free. Free endpoints pass through without OTP or
163
+ pay gate configuration.
164
+ - Listed endpoints block unless a valid OTP is supplied.
165
+
166
+ ### Token format
167
+
168
+ OTP tokens are a dependency-free compact envelope:
169
+
170
+ ```
171
+ <base64url(payloadJson)>.<base64url(signature)>
172
+ ```
173
+
174
+ The payload JSON is canonicalized with sorted object keys before signing.
175
+ Signature is Ed25519 over the exact base64url payload segment bytes.
176
+
177
+ Payload schema:
178
+
179
+ ```ts
180
+ interface PayGateOtpPayload {
181
+ v: 1; // version
182
+ jti: string; // random 128-bit hex (unique token id)
183
+ provider: string; // e.g. "kie"
184
+ method: string; // e.g. "POST"
185
+ dotPath: string; // e.g. "api.v1.jobs.createTask"
186
+ requestHash: `sha256:${string}`; // sha256 of canonical request JSON
187
+ maxSpendUsd: number; // maximum allowed spend in USD
188
+ iat: number; // issued-at unix seconds
189
+ exp: number; // expiration unix seconds
190
+ }
191
+ ```
192
+
193
+ Request hash is `sha256:` + hex SHA-256 of the canonical JSON for the request
194
+ payload. Object keys are sorted recursively; array order is preserved.
195
+ Non-JSON payload values must fail closed.
196
+
197
+ ### Key configuration
198
+
199
+ **Runtime (verification):**
200
+
201
+ | Variable | Required | Description |
202
+ |----------|----------|-------------|
203
+ | `APICITY_PAYGATE_PUBLIC_KEY_PATH` | Yes | Path to an Ed25519 public key PEM file. Without this, the pay gate is disabled and all paid endpoints throw `PayGateError`. |
204
+
205
+ **CLI (minting):**
206
+
207
+ | Variable | Required | Description |
208
+ |----------|----------|-------------|
209
+ | `APICITY_PAYGATE_PRIVATE_KEY_PATH` | Yes | Path to an Ed25519 private key PEM file. Used by the `apicity-paygate` CLI to sign OTPs. |
210
+
211
+ ### Request canonicalization
212
+
213
+ Before hashing, the request payload is canonicalized:
214
+
215
+ 1. Serialize to JSON with **sorted object keys** (recursive).
216
+ 2. Preserve array order exactly.
217
+ 3. Reject non-JSON values (functions, undefined, circular references, etc.).
218
+
219
+ The canonical JSON string is then SHA-256 hashed, and the hash is prefixed
220
+ with `sha256:` in the OTP payload.
221
+
222
+ ### Replay ledger
223
+
224
+ Consumed OTPs are recorded immediately before dispatch to prevent replay
225
+ attacks. The default ledger path:
226
+
227
+ - `$XDG_STATE_HOME/apicity/paygate-used.jsonl`
228
+ - Fallback: `~/.local/state/apicity/paygate-used.jsonl`
229
+
230
+ Each line is a JSON object: `{ "jti": "...", "consumedAt": 1234567890 }`.
231
+
232
+ If dispatch later fails (network error, upstream 500, etc.), the OTP remains
233
+ consumed. The operator must mint a new OTP for retry.
234
+
235
+ ### Public interface
236
+
237
+ ```ts
238
+ interface PayGateApproval {
239
+ otp: string;
240
+ }
241
+
242
+ async function dispatchWithPaidGate<T>(
243
+ provider: string,
244
+ method: string,
245
+ dotPath: string,
246
+ payload: Record<string, unknown>,
247
+ approval: PayGateApproval | undefined,
248
+ dispatch: () => Promise<T>
249
+ ): Promise<T>;
250
+ ```
251
+
252
+ Paid endpoint APIs pass the approval as an options object:
253
+
254
+ ```ts
255
+ import { kie } from "@apicity/kie";
256
+
257
+ const provider = kie({ apiKey: process.env.KIE_API_KEY! });
258
+
259
+ const task = await provider.post.api.v1.jobs.createTask(
260
+ {
261
+ model: "kling-3.0/video",
262
+ input: { prompt: "...", duration: "5", aspect_ratio: "16:9" },
263
+ },
264
+ { otp: "eyJ2IjoxLCJqdGkiOi4uLn0.uK2J9..." }
265
+ );
266
+ ```
267
+
268
+ ### Guard behavior
269
+
270
+ 1. **Preflight** — before any network dispatch, `dispatchWithPaidGate` checks
271
+ whether the endpoint is paid. If the runtime lacks
272
+ `APICITY_PAYGATE_PUBLIC_KEY_PATH`, the call throws `PayGateError`.
273
+ 2. **OTP presence** — paid endpoints require `approval.otp`. If omitted, the
274
+ call throws `PayGateError`.
275
+ 3. **Signature verification** — the OTP payload segment is verified against
276
+ the Ed25519 public key. If the signature is invalid or forged, the call
277
+ throws `PayGateError`.
278
+ 4. **Expiration** — if `exp` is in the past, the call throws `PayGateError`.
279
+ 5. **Request binding** — the OTP `provider`, `method`, `dotPath`, and
280
+ `requestHash` must match the actual call. Any mismatch throws
281
+ `PayGateError`.
282
+ 6. **Replay check** — if the OTP `jti` already exists in the ledger, the call
283
+ throws `PayGateError`.
284
+ 7. **Estimate** — the package computes a local cost estimate from the payload.
285
+ 8. **Bound check** — if the estimate exceeds `maxSpendUsd`, or if the cost
286
+ cannot be estimated (unknown model, missing fields), the call throws
287
+ `SpendBoundError`.
288
+ 9. **Consume** — the `jti` is appended to the replay ledger.
289
+ 10. **Dispatch** — only when all checks pass does the actual HTTP request fire.
290
+
291
+ ```ts
292
+ import { PayGateError, SpendBoundError } from "@apicity/cost";
293
+
294
+ try {
295
+ await provider.post.api.v1.jobs.createTask({ ... }, { otp: "..." });
296
+ } catch (e) {
297
+ if (e instanceof PayGateError) {
298
+ // OTP missing, invalid, expired, replayed, or mismatched request
299
+ }
300
+ if (e instanceof SpendBoundError) {
301
+ // estimated cost > maxSpendUsd, or cost could not be computed
302
+ }
303
+ }
304
+ ```
305
+
306
+ ### Failure modes
307
+
308
+ | Condition | Error | Notes |
309
+ |-----------|-------|-------|
310
+ | No `APICITY_PAYGATE_PUBLIC_KEY_PATH` | `PayGateError` | Pay gate is not configured |
311
+ | Paid endpoint without OTP | `PayGateError` | Caller must pass `approval.otp` |
312
+ | Invalid signature | `PayGateError` | OTP was not signed by the correct key |
313
+ | Expired OTP (`exp` < now) | `PayGateError` | Operator must mint a fresh OTP |
314
+ | Replayed OTP (`jti` in ledger) | `PayGateError` | Each OTP is single-use |
315
+ | Mismatched provider/method/dotPath | `PayGateError` | OTP is bound to a specific call |
316
+ | Mismatched request hash | `PayGateError` | Payload must match exactly |
317
+ | Estimate > `maxSpendUsd` | `SpendBoundError` | Request is too expensive |
318
+ | Unestimable cost | `SpendBoundError` | Unknown model or missing fields |
319
+
320
+ ### CLI: minting OTPs
321
+
322
+ The `apicity-paygate` binary from `@apicity/cost` mints operator-signed OTPs:
323
+
324
+ ```bash
325
+ # Mint an OTP for a specific request
326
+ apicity-paygate otp mint \
327
+ --provider kie \
328
+ --method POST \
329
+ --dot-path api.v1.jobs.createTask \
330
+ --payload-file request.json \
331
+ --max-spend 5 \
332
+ --ttl 10m
333
+ ```
334
+
335
+ The CLI requires `APICITY_PAYGATE_PRIVATE_KEY_PATH` and prints only the OTP
336
+ to stdout on success.
337
+
338
+ ### Migration from `maxSpend`
339
+
340
+ The previous numeric `maxSpend` parameter is **deprecated**. It allowed
341
+ autonomous callers to self-approve by passing any positive number, which is
342
+ not a true authority boundary.
343
+
344
+ Migration path:
345
+
346
+ 1. **Operator** generates an Ed25519 key pair:
347
+ ```bash
348
+ openssl genpkey -algorithm Ed25519 -out paygate-private.pem
349
+ openssl pkey -in paygate-private.pem -pubout -out paygate-public.pem
350
+ ```
351
+ 2. **Runtime** sets `APICITY_PAYGATE_PUBLIC_KEY_PATH` to the public key.
352
+ 3. **Operator** mints OTPs before each paid call using the CLI or a custom
353
+ tool that signs the same payload format.
354
+ 4. **Caller** passes `{ otp }` instead of a numeric `maxSpend`:
355
+ ```ts
356
+ // Before (deprecated)
357
+ await provider.post.api.v1.jobs.createTask({ ... }, 5);
358
+
359
+ // After
360
+ await provider.post.api.v1.jobs.createTask({ ... }, { otp: "..." });
361
+ ```
362
+
363
+ The old `maxSpendPreflight`, `MaxSpendError`, and `dispatchWithPaidGuard`
364
+ interfaces are retained during the transition but will be removed in a
365
+ future major version.
366
+
367
+ ### Minimal operator workflow
368
+
369
+ 1. **Set up keys** (one-time):
370
+ ```bash
371
+ export APICITY_PAYGATE_PRIVATE_KEY_PATH=./paygate-private.pem
372
+ export APICITY_PAYGATE_PUBLIC_KEY_PATH=./paygate-public.pem
373
+ ```
374
+ 2. **Prepare a request**:
375
+ ```bash
376
+ cat > request.json << 'EOF'
377
+ {
378
+ "model": "kling-3.0/video",
379
+ "input": {
380
+ "prompt": "A cat playing piano",
381
+ "duration": "5",
382
+ "aspect_ratio": "16:9"
383
+ }
384
+ }
385
+ EOF
386
+ ```
387
+ 3. **Mint an OTP**:
388
+ ```bash
389
+ apicity-paygate otp mint \
390
+ --provider kie \
391
+ --method POST \
392
+ --dot-path api.v1.jobs.createTask \
393
+ --payload-file request.json \
394
+ --max-spend 5 \
395
+ --ttl 10m
396
+ ```
397
+ 4. **Pass the OTP to the caller** (copy-paste, secrets manager, etc.).
398
+ 5. **Caller uses the OTP**:
399
+ ```ts
400
+ await provider.post.api.v1.jobs.createTask({ ... }, { otp: "<paste>" });
401
+ ```
402
+
145
403
  ## Out of scope
146
404
 
147
405
  - Anthropic prompt-cache pricing (rates are in the table but `estimate()` ignores them — assumes no caching)
@@ -6,4 +6,8 @@ export type { SlugProviderId, SlugModelId } from "./slugs";
6
6
  export type { CostUnit, ModelPricing, PerUnitPricing, PricedProviderId, RateSource, TokenPricing, } from "./pricing/index";
7
7
  export type { CostBreakdown, CostEstimate, CostProvider, CostSource, EstimateRequest, } from "./types";
8
8
  export type { ExtractResult, TextExtract } from "./extract/types";
9
+ export { PAID_ENDPOINTS, lookupPaidEndpoint, isPaidEndpoint, maxSpendPreflight, MaxSpendError, SpendBoundError, spendBoundCheck, dispatchWithPaidGuard, } from "./paid-endpoints";
10
+ export type { PaidEndpointKey, PaidEndpointInfo, PaidEndpointEntry, } from "./paid-endpoints";
11
+ export { PayGateError, PayGateApproval, dispatchWithPaidGate, canonicalizeJson, canonicalHash, parseOtp, verifyOtpSignature, isJtiConsumed, consumeJti, } from "./paygate";
12
+ export type { PayGateOtpPayload } from "./paygate";
9
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC9E,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3D,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC9E,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3D,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAElE,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,eAAe,EACf,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,UAAU,GACX,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC"}
package/dist/src/index.js CHANGED
@@ -2,4 +2,6 @@ export { cost } from "./cost.js";
2
2
  export { computeEstimate } from "./compute.js";
3
3
  export { PRICING, PRICING_AS_OF } from "./pricing/index.js";
4
4
  export { MODEL_SLUGS, MODEL_DISPLAY, modelSlug, modelDisplay } from "./slugs.js";
5
+ export { PAID_ENDPOINTS, lookupPaidEndpoint, isPaidEndpoint, maxSpendPreflight, MaxSpendError, SpendBoundError, spendBoundCheck, dispatchWithPaidGuard, } from "./paid-endpoints.js";
6
+ export { PayGateError, dispatchWithPaidGate, canonicalizeJson, canonicalHash, parseOtp, verifyOtpSignature, isJtiConsumed, consumeJti, } from "./paygate.js";
5
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAsB9E,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,eAAe,EACf,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EACL,YAAY,EAEZ,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,UAAU,GACX,MAAM,WAAW,CAAC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Exact paid-endpoint registry.
3
+ *
4
+ * Only endpoints listed here are considered paid. All unlisted endpoints
5
+ * are assumed free and must preserve current behavior with no caller changes.
6
+ *
7
+ * Matching is exact: provider + method + dotPath. No regex, prefix,
8
+ * wildcard, path-family, generated broad match, or fallback-by-method logic.
9
+ */
10
+ export interface PaidEndpointKey {
11
+ provider: string;
12
+ method: string;
13
+ dotPath: string;
14
+ }
15
+ export interface PaidEndpointInfo {
16
+ /** Human-readable reason why this endpoint is paid. */
17
+ reason: string;
18
+ /** Optional estimator identifier for cost computation. */
19
+ estimatorId?: string;
20
+ /** Optional known cost notes (e.g. per-unit billing details). */
21
+ costNotes?: string;
22
+ }
23
+ export interface PaidEndpointEntry {
24
+ key: PaidEndpointKey;
25
+ info: PaidEndpointInfo;
26
+ }
27
+ /**
28
+ * The canonical list of paid endpoints. Add new entries here only after
29
+ * review. Keep the list small and explicit.
30
+ */
31
+ export declare const PAID_ENDPOINTS: readonly PaidEndpointEntry[];
32
+ /**
33
+ * Look up a paid endpoint by exact key match.
34
+ *
35
+ * Returns `PaidEndpointInfo` only when provider, method, and dotPath all match
36
+ * an entry in `PAID_ENDPOINTS` exactly. Returns `undefined` for every
37
+ * unlisted endpoint, which callers must treat as free.
38
+ */
39
+ export declare function lookupPaidEndpoint(provider: string, method: string, dotPath: string): PaidEndpointInfo | undefined;
40
+ /**
41
+ * Predicate: is this exact endpoint paid?
42
+ *
43
+ * Unlisted endpoints return `false` (assumed free).
44
+ */
45
+ export declare function isPaidEndpoint(provider: string, method: string, dotPath: string): boolean;
46
+ /**
47
+ * Error thrown when a paid endpoint is called without an explicit maxSpend.
48
+ */
49
+ export declare class MaxSpendError extends Error {
50
+ readonly provider: string;
51
+ readonly method: string;
52
+ readonly dotPath: string;
53
+ readonly maxSpend: number;
54
+ constructor(provider: string, method: string, dotPath: string, maxSpend: number);
55
+ }
56
+ /**
57
+ * Error thrown when the estimated cost of a paid endpoint exceeds the
58
+ * caller's maxSpend or when the cost cannot be safely estimated.
59
+ */
60
+ export declare class SpendBoundError extends Error {
61
+ readonly provider: string;
62
+ readonly method: string;
63
+ readonly dotPath: string;
64
+ readonly maxSpend: number;
65
+ readonly estimatedUsd: number;
66
+ constructor(provider: string, method: string, dotPath: string, maxSpend: number, estimatedUsd: number, message?: string);
67
+ }
68
+ /**
69
+ * Preflight check for paid endpoints.
70
+ *
71
+ * For paid endpoints, maxSpend defaults to 0 when omitted. maxSpend=0 blocks
72
+ * before the network request with a MaxSpendError. maxSpend>0 authorizes the
73
+ * call to proceed.
74
+ *
75
+ * Free/unlisted endpoints are always allowed regardless of maxSpend.
76
+ */
77
+ export declare function maxSpendPreflight(provider: string, method: string, dotPath: string, maxSpend?: number): void;
78
+ /**
79
+ * Verify that a cost estimate is within the caller's maxSpend.
80
+ *
81
+ * If the estimate has warnings (could not be computed safely), the spend
82
+ * cannot be bounded and the call is blocked. If the estimated USD exceeds
83
+ * maxSpend, the call is blocked. Otherwise the call proceeds.
84
+ *
85
+ * This must run AFTER maxSpendPreflight, so maxSpend is known to be > 0.
86
+ */
87
+ export declare function spendBoundCheck(provider: string, method: string, dotPath: string, maxSpend: number | undefined, estimate: {
88
+ usd: number;
89
+ warnings: string[];
90
+ }): void;
91
+ /**
92
+ * Wrap a provider network dispatch with the paid-endpoint guard.
93
+ *
94
+ * This is the canonical boundary enforcement: it runs the preflight check
95
+ * and spend-bound check before the actual HTTP request, and only calls the
96
+ * supplied `dispatch` function when the checks pass.
97
+ *
98
+ * Free/unlisted endpoints return `dispatch()` immediately without guard
99
+ * overhead, so callers that omit `maxSpend` on free endpoints see no change.
100
+ *
101
+ * @param provider - Provider identifier (e.g. "kie", "openai")
102
+ * @param method - HTTP method (e.g. "POST", "GET")
103
+ * @param dotPath - Exact endpoint dot-path (e.g. "api.v1.jobs.createTask")
104
+ * @param payload - Request payload for cost estimation
105
+ * @param maxSpend - Maximum spend authorization in USD (undefined for free endpoints)
106
+ * @param dispatch - The actual network dispatch to wrap
107
+ * @returns The result of `dispatch()`
108
+ */
109
+ export declare function dispatchWithPaidGuard<T>(provider: string, method: string, dotPath: string, payload: Record<string, unknown>, maxSpend: number | undefined, dispatch: () => Promise<T>): Promise<T>;
110
+ //# sourceMappingURL=paid-endpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paid-endpoints.d.ts","sourceRoot":"","sources":["../../src/paid-endpoints.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AAEH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,eAAe,CAAC;IACrB,IAAI,EAAE,gBAAgB,CAAC;CACxB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,iBAAiB,EAetD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,gBAAgB,GAAG,SAAS,CAW9B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAET;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAExB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM;CAanB;AACD;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAE5B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM;CAcnB;AACD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAU,GACnB,IAAI,CAON;AACD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GAC5C,IAAI,CA0BN;AACD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAC3C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAcZ"}
@@ -0,0 +1,157 @@
1
+ import { computeEstimate } from "./compute.js";
2
+ /**
3
+ * The canonical list of paid endpoints. Add new entries here only after
4
+ * review. Keep the list small and explicit.
5
+ */
6
+ export const PAID_ENDPOINTS = [
7
+ {
8
+ key: {
9
+ provider: "kie",
10
+ method: "POST",
11
+ dotPath: "api.v1.jobs.createTask",
12
+ },
13
+ info: {
14
+ reason: "Media generation task that incurs direct marginal compute cost per job",
15
+ estimatorId: "kie-per-unit",
16
+ costNotes: "Billed per unit (seconds/images/songs) based on model and resolution",
17
+ },
18
+ },
19
+ ];
20
+ /**
21
+ * Look up a paid endpoint by exact key match.
22
+ *
23
+ * Returns `PaidEndpointInfo` only when provider, method, and dotPath all match
24
+ * an entry in `PAID_ENDPOINTS` exactly. Returns `undefined` for every
25
+ * unlisted endpoint, which callers must treat as free.
26
+ */
27
+ export function lookupPaidEndpoint(provider, method, dotPath) {
28
+ for (const entry of PAID_ENDPOINTS) {
29
+ if (entry.key.provider === provider &&
30
+ entry.key.method === method &&
31
+ entry.key.dotPath === dotPath) {
32
+ return entry.info;
33
+ }
34
+ }
35
+ return undefined;
36
+ }
37
+ /**
38
+ * Predicate: is this exact endpoint paid?
39
+ *
40
+ * Unlisted endpoints return `false` (assumed free).
41
+ */
42
+ export function isPaidEndpoint(provider, method, dotPath) {
43
+ return lookupPaidEndpoint(provider, method, dotPath) !== undefined;
44
+ }
45
+ /**
46
+ * Error thrown when a paid endpoint is called without an explicit maxSpend.
47
+ */
48
+ export class MaxSpendError extends Error {
49
+ provider;
50
+ method;
51
+ dotPath;
52
+ maxSpend;
53
+ constructor(provider, method, dotPath, maxSpend) {
54
+ super(`Endpoint ${provider} ${method} ${dotPath} may spend money. ` +
55
+ `maxSpend is ${maxSpend} USD. ` +
56
+ `Pass an explicit maxSpend to proceed.`);
57
+ this.name = "MaxSpendError";
58
+ this.provider = provider;
59
+ this.method = method;
60
+ this.dotPath = dotPath;
61
+ this.maxSpend = maxSpend;
62
+ }
63
+ }
64
+ /**
65
+ * Error thrown when the estimated cost of a paid endpoint exceeds the
66
+ * caller's maxSpend or when the cost cannot be safely estimated.
67
+ */
68
+ export class SpendBoundError extends Error {
69
+ provider;
70
+ method;
71
+ dotPath;
72
+ maxSpend;
73
+ estimatedUsd;
74
+ constructor(provider, method, dotPath, maxSpend, estimatedUsd, message) {
75
+ super(message ??
76
+ `Endpoint ${provider} ${method} ${dotPath} estimated cost ` +
77
+ `(${estimatedUsd} USD) exceeds maxSpend (${maxSpend} USD).`);
78
+ this.name = "SpendBoundError";
79
+ this.provider = provider;
80
+ this.method = method;
81
+ this.dotPath = dotPath;
82
+ this.maxSpend = maxSpend;
83
+ this.estimatedUsd = estimatedUsd;
84
+ }
85
+ }
86
+ /**
87
+ * Preflight check for paid endpoints.
88
+ *
89
+ * For paid endpoints, maxSpend defaults to 0 when omitted. maxSpend=0 blocks
90
+ * before the network request with a MaxSpendError. maxSpend>0 authorizes the
91
+ * call to proceed.
92
+ *
93
+ * Free/unlisted endpoints are always allowed regardless of maxSpend.
94
+ */
95
+ export function maxSpendPreflight(provider, method, dotPath, maxSpend = 0) {
96
+ if (!isPaidEndpoint(provider, method, dotPath)) {
97
+ return;
98
+ }
99
+ if (maxSpend <= 0) {
100
+ throw new MaxSpendError(provider, method, dotPath, maxSpend);
101
+ }
102
+ }
103
+ /**
104
+ * Verify that a cost estimate is within the caller's maxSpend.
105
+ *
106
+ * If the estimate has warnings (could not be computed safely), the spend
107
+ * cannot be bounded and the call is blocked. If the estimated USD exceeds
108
+ * maxSpend, the call is blocked. Otherwise the call proceeds.
109
+ *
110
+ * This must run AFTER maxSpendPreflight, so maxSpend is known to be > 0.
111
+ */
112
+ export function spendBoundCheck(provider, method, dotPath, maxSpend, estimate) {
113
+ if (maxSpend === undefined || maxSpend <= 0) {
114
+ return;
115
+ }
116
+ if (estimate.warnings.length > 0) {
117
+ throw new SpendBoundError(provider, method, dotPath, maxSpend, estimate.usd, `Endpoint ${provider} ${method} ${dotPath} spend cannot be bounded ` +
118
+ `from the payload: ${estimate.warnings.join("; ")}. ` +
119
+ `Pass an explicit maxSpend that covers the worst-case cost, ` +
120
+ `or adjust the payload so the cost can be estimated.`);
121
+ }
122
+ if (estimate.usd > maxSpend) {
123
+ throw new SpendBoundError(provider, method, dotPath, maxSpend, estimate.usd);
124
+ }
125
+ }
126
+ /**
127
+ * Wrap a provider network dispatch with the paid-endpoint guard.
128
+ *
129
+ * This is the canonical boundary enforcement: it runs the preflight check
130
+ * and spend-bound check before the actual HTTP request, and only calls the
131
+ * supplied `dispatch` function when the checks pass.
132
+ *
133
+ * Free/unlisted endpoints return `dispatch()` immediately without guard
134
+ * overhead, so callers that omit `maxSpend` on free endpoints see no change.
135
+ *
136
+ * @param provider - Provider identifier (e.g. "kie", "openai")
137
+ * @param method - HTTP method (e.g. "POST", "GET")
138
+ * @param dotPath - Exact endpoint dot-path (e.g. "api.v1.jobs.createTask")
139
+ * @param payload - Request payload for cost estimation
140
+ * @param maxSpend - Maximum spend authorization in USD (undefined for free endpoints)
141
+ * @param dispatch - The actual network dispatch to wrap
142
+ * @returns The result of `dispatch()`
143
+ */
144
+ export async function dispatchWithPaidGuard(provider, method, dotPath, payload, maxSpend, dispatch) {
145
+ maxSpendPreflight(provider, method, dotPath, maxSpend);
146
+ if (isPaidEndpoint(provider, method, dotPath) &&
147
+ maxSpend !== undefined &&
148
+ maxSpend > 0) {
149
+ const estimate = computeEstimate({
150
+ provider: provider,
151
+ payload,
152
+ });
153
+ spendBoundCheck(provider, method, dotPath, maxSpend, estimate);
154
+ }
155
+ return dispatch();
156
+ }
157
+ //# sourceMappingURL=paid-endpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paid-endpoints.js","sourceRoot":"","sources":["../../src/paid-endpoints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Parse a TTL string like "10m", "1h", "30s" into seconds.
4
+ */
5
+ export declare function parseTtl(ttl: string): number;
6
+ /**
7
+ * Mint an OTP for a specific request.
8
+ *
9
+ * Requires `APICITY_PAYGATE_PRIVATE_KEY_PATH` to point to an Ed25519 private key PEM.
10
+ */
11
+ export declare function mintOtp(provider: string, method: string, dotPath: string, payload: Record<string, unknown>, maxSpendUsd: number, ttlSeconds: number): string;
12
+ /**
13
+ * Generate a fresh Ed25519 key pair for the pay gate.
14
+ */
15
+ export declare function generateKeyPair(): {
16
+ publicKeyPem: string;
17
+ privateKeyPem: string;
18
+ };
19
+ //# sourceMappingURL=paygate-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paygate-cli.d.ts","sourceRoot":"","sources":["../../src/paygate-cli.ts"],"names":[],"mappings":";AAkBA;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAqB5C;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,MAAM,CAuCR;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB,CAMA"}
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env node
2
+ import { sign, generateKeyPairSync, randomBytes } from "node:crypto";
3
+ import { readFileSync } from "node:fs";
4
+ import { fileURLToPath } from "node:url";
5
+ import { canonicalHash } from "./paygate.js";
6
+ /**
7
+ * Encode a buffer to unpadded base64url.
8
+ */
9
+ function base64urlEncode(data) {
10
+ return data
11
+ .toString("base64")
12
+ .replace(/\+/g, "-")
13
+ .replace(/\//g, "_")
14
+ .replace(/=+$/g, "");
15
+ }
16
+ /**
17
+ * Parse a TTL string like "10m", "1h", "30s" into seconds.
18
+ */
19
+ export function parseTtl(ttl) {
20
+ const match = ttl.match(/^(\d+)([smhd])$/i);
21
+ if (!match) {
22
+ throw new Error(`Invalid TTL format: ${ttl}. Expected format like 10m, 1h, 30s.`);
23
+ }
24
+ const value = parseInt(match[1], 10);
25
+ const unit = match[2].toLowerCase();
26
+ switch (unit) {
27
+ case "s":
28
+ return value;
29
+ case "m":
30
+ return value * 60;
31
+ case "h":
32
+ return value * 60 * 60;
33
+ case "d":
34
+ return value * 60 * 60 * 24;
35
+ default:
36
+ throw new Error(`Unknown TTL unit: ${unit}`);
37
+ }
38
+ }
39
+ /**
40
+ * Mint an OTP for a specific request.
41
+ *
42
+ * Requires `APICITY_PAYGATE_PRIVATE_KEY_PATH` to point to an Ed25519 private key PEM.
43
+ */
44
+ export function mintOtp(provider, method, dotPath, payload, maxSpendUsd, ttlSeconds) {
45
+ const privateKeyPath = process.env.APICITY_PAYGATE_PRIVATE_KEY_PATH;
46
+ if (!privateKeyPath) {
47
+ throw new Error("APICITY_PAYGATE_PRIVATE_KEY_PATH is not set. " +
48
+ "Export the path to your Ed25519 private key PEM.");
49
+ }
50
+ const privateKeyPem = readFileSync(privateKeyPath, "utf8");
51
+ const jti = randomBytes(16).toString("hex");
52
+ const iat = Math.floor(Date.now() / 1000);
53
+ const exp = iat + ttlSeconds;
54
+ const payloadObj = {
55
+ v: 1,
56
+ jti,
57
+ provider,
58
+ method,
59
+ dotPath,
60
+ requestHash: canonicalHash(payload),
61
+ maxSpendUsd,
62
+ iat,
63
+ exp,
64
+ };
65
+ const payloadJson = JSON.stringify(payloadObj);
66
+ const payloadSegment = base64urlEncode(Buffer.from(payloadJson, "utf8"));
67
+ const signature = sign(null, Buffer.from(payloadSegment, "utf8"), privateKeyPem);
68
+ const signatureSegment = base64urlEncode(signature);
69
+ return `${payloadSegment}.${signatureSegment}`;
70
+ }
71
+ /**
72
+ * Generate a fresh Ed25519 key pair for the pay gate.
73
+ */
74
+ export function generateKeyPair() {
75
+ const { publicKey, privateKey } = generateKeyPairSync("ed25519", {
76
+ publicKeyEncoding: { type: "spki", format: "pem" },
77
+ privateKeyEncoding: { type: "pkcs8", format: "pem" },
78
+ });
79
+ return { publicKeyPem: publicKey, privateKeyPem: privateKey };
80
+ }
81
+ function parseMintArgs(argv) {
82
+ const out = {};
83
+ for (let i = 0; i < argv.length; i++) {
84
+ const a = argv[i];
85
+ if (a === "--provider")
86
+ out.provider = argv[++i];
87
+ else if (a.startsWith("--provider="))
88
+ out.provider = a.slice(11);
89
+ else if (a === "--method")
90
+ out.method = argv[++i];
91
+ else if (a.startsWith("--method="))
92
+ out.method = a.slice(9);
93
+ else if (a === "--dot-path")
94
+ out.dotPath = argv[++i];
95
+ else if (a.startsWith("--dot-path="))
96
+ out.dotPath = a.slice(11);
97
+ else if (a === "--payload-file")
98
+ out.payloadFile = argv[++i];
99
+ else if (a.startsWith("--payload-file="))
100
+ out.payloadFile = a.slice(15);
101
+ else if (a === "--max-spend")
102
+ out.maxSpend = parseFloat(argv[++i]);
103
+ else if (a.startsWith("--max-spend="))
104
+ out.maxSpend = parseFloat(a.slice(12));
105
+ else if (a === "--ttl")
106
+ out.ttl = argv[++i];
107
+ else if (a.startsWith("--ttl="))
108
+ out.ttl = a.slice(6);
109
+ else {
110
+ console.error(`[apicity-paygate] unknown arg: ${a}`);
111
+ }
112
+ }
113
+ const required = [
114
+ "provider",
115
+ "method",
116
+ "dotPath",
117
+ "payloadFile",
118
+ "maxSpend",
119
+ "ttl",
120
+ ];
121
+ for (const key of required) {
122
+ if (out[key] === undefined || out[key] === null) {
123
+ throw new Error(`Missing required argument: --${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`);
124
+ }
125
+ }
126
+ return out;
127
+ }
128
+ function printHelp() {
129
+ console.error([
130
+ "apicity-paygate — Mint OTPs for paid @apicity endpoints.",
131
+ "",
132
+ "Usage:",
133
+ " apicity-paygate otp mint \\",
134
+ " --provider <provider> \\",
135
+ " --method <HTTP method> \\",
136
+ " --dot-path <api.path> \\",
137
+ " --payload-file <path> \\",
138
+ " --max-spend <usd> \\",
139
+ " --ttl <duration>",
140
+ "",
141
+ "Options:",
142
+ " --provider Provider name (e.g. kie, openai, xai)",
143
+ " --method HTTP method (e.g. POST, GET)",
144
+ " --dot-path API dot-path (e.g. api.v1.jobs.createTask)",
145
+ " --payload-file Path to JSON request payload file",
146
+ " --max-spend Maximum spend in USD",
147
+ " --ttl Time-to-live: 10m, 1h, 30s, 1d",
148
+ "",
149
+ "Environment:",
150
+ " APICITY_PAYGATE_PRIVATE_KEY_PATH Path to Ed25519 private key PEM",
151
+ ].join("\n"));
152
+ }
153
+ async function main() {
154
+ const argv = process.argv.slice(2);
155
+ if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
156
+ printHelp();
157
+ process.exit(0);
158
+ }
159
+ if (argv[0] !== "otp" || argv[1] !== "mint") {
160
+ console.error("[apicity-paygate] only 'otp mint' is supported.");
161
+ printHelp();
162
+ process.exit(1);
163
+ }
164
+ const args = parseMintArgs(argv.slice(2));
165
+ const payload = JSON.parse(readFileSync(args.payloadFile, "utf8"));
166
+ const ttlSeconds = parseTtl(args.ttl);
167
+ const otp = mintOtp(args.provider, args.method, args.dotPath, payload, args.maxSpend, ttlSeconds);
168
+ console.log(otp);
169
+ }
170
+ const __filename = fileURLToPath(import.meta.url);
171
+ if (process.argv[1] === __filename) {
172
+ main().catch((err) => {
173
+ console.error("[apicity-paygate] fatal:", err instanceof Error ? err.message : err);
174
+ process.exit(1);
175
+ });
176
+ }
177
+ //# sourceMappingURL=paygate-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paygate-cli.js","sourceRoot":"","sources":["../../src/paygate-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * OTP payload schema.
3
+ */
4
+ export interface PayGateOtpPayload {
5
+ v: 1;
6
+ jti: string;
7
+ provider: string;
8
+ method: string;
9
+ dotPath: string;
10
+ requestHash: `sha256:${string}`;
11
+ maxSpendUsd: number;
12
+ iat: number;
13
+ exp: number;
14
+ }
15
+ /**
16
+ * Caller-supplied approval object.
17
+ */
18
+ export interface PayGateApproval {
19
+ otp: string;
20
+ }
21
+ /**
22
+ * Error thrown when the pay gate blocks a request for any reason
23
+ * other than spend bounds (which use SpendBoundError).
24
+ */
25
+ export declare class PayGateError extends Error {
26
+ readonly provider: string;
27
+ readonly method: string;
28
+ readonly dotPath: string;
29
+ readonly code: "paygate-not-configured" | "otp-missing" | "otp-malformed" | "otp-invalid-signature" | "otp-expired" | "otp-mismatched-request" | "otp-replayed";
30
+ constructor(provider: string, method: string, dotPath: string, code: PayGateError["code"], message: string);
31
+ }
32
+ /**
33
+ * Canonicalize a JSON value by sorting object keys recursively.
34
+ * Arrays preserve order. Non-JSON values (undefined, functions, symbols,
35
+ * circular references) cause a TypeError so the caller can fail closed.
36
+ */
37
+ export declare function canonicalizeJson(value: unknown): string;
38
+ /**
39
+ * Compute SHA-256 of canonical JSON, prefixed with `sha256:`.
40
+ */
41
+ export declare function canonicalHash(value: unknown): `sha256:${string}`;
42
+ /**
43
+ * Parse an OTP envelope: `<base64url(payloadJson)>.<base64url(signature)>`.
44
+ * Returns the payload object and raw signature bytes.
45
+ */
46
+ export declare function parseOtp(otp: string): {
47
+ payload: PayGateOtpPayload;
48
+ signature: Buffer;
49
+ };
50
+ /**
51
+ * Verify the Ed25519 signature of an OTP payload segment.
52
+ * `publicKey` is the PEM string read from the public key file.
53
+ */
54
+ export declare function verifyOtpSignature(payloadSegmentBase64url: string, signature: Buffer, publicKeyPem: string): boolean;
55
+ /**
56
+ * Check whether a jti has already been consumed.
57
+ *
58
+ * @param jti - The OTP jti to check
59
+ * @param ledgerPath - Optional override path; defaults to XDG_STATE_HOME or ~/.local/state
60
+ */
61
+ export declare function isJtiConsumed(jti: string, ledgerPath?: string): boolean;
62
+ /**
63
+ * Append a jti to the replay ledger.
64
+ *
65
+ * @param jti - The OTP jti to consume
66
+ * @param ledgerPath - Optional override path; defaults to XDG_STATE_HOME or ~/.local/state
67
+ */
68
+ export declare function consumeJti(jti: string, ledgerPath?: string): void;
69
+ /**
70
+ * Wrap a provider network dispatch with the OTP-based paid-endpoint gate.
71
+ *
72
+ * Free/unlisted endpoints return `dispatch()` immediately without OTP or
73
+ * pay gate configuration.
74
+ *
75
+ * Paid endpoints fail closed: if the pay gate is not configured, or the OTP
76
+ * is missing, invalid, expired, replayed, mismatched, or the cost exceeds the
77
+ * OTP's maxSpendUsd, the call throws before dispatch runs.
78
+ */
79
+ export declare function dispatchWithPaidGate<T>(provider: string, method: string, dotPath: string, payload: Record<string, unknown>, approval: PayGateApproval | undefined, dispatch: () => Promise<T>): Promise<T>;
80
+ //# sourceMappingURL=paygate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paygate.d.ts","sourceRoot":"","sources":["../../src/paygate.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,CAAC,EAAE,CAAC,CAAC;IACL,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,UAAU,MAAM,EAAE,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EACT,wBAAwB,GACxB,aAAa,GACb,eAAe,GACf,uBAAuB,GACvB,aAAa,GACb,wBAAwB,GACxB,cAAc,CAAC;gBAGjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,EAC1B,OAAO,EAAE,MAAM;CASlB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAsCvD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,MAAM,EAAE,CAIhE;AAaD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG;IACrC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB,CAyCA;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,uBAAuB,EAAE,MAAM,EAC/B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAIT;AAaD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAA4B,GACvC,OAAO,CAkBT;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAA4B,GACvC,IAAI,CAUN;AAuGD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,eAAe,GAAG,SAAS,EACrC,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAsEZ"}
@@ -0,0 +1,278 @@
1
+ import { createHash, createPublicKey, verify } from "node:crypto";
2
+ import { readFileSync, appendFileSync, existsSync, mkdirSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { homedir } from "node:os";
5
+ import { computeEstimate } from "./compute.js";
6
+ import { isPaidEndpoint } from "./paid-endpoints.js";
7
+ import { SpendBoundError } from "./paid-endpoints.js";
8
+ /**
9
+ * Error thrown when the pay gate blocks a request for any reason
10
+ * other than spend bounds (which use SpendBoundError).
11
+ */
12
+ export class PayGateError extends Error {
13
+ provider;
14
+ method;
15
+ dotPath;
16
+ code;
17
+ constructor(provider, method, dotPath, code, message) {
18
+ super(message);
19
+ this.name = "PayGateError";
20
+ this.provider = provider;
21
+ this.method = method;
22
+ this.dotPath = dotPath;
23
+ this.code = code;
24
+ }
25
+ }
26
+ /**
27
+ * Canonicalize a JSON value by sorting object keys recursively.
28
+ * Arrays preserve order. Non-JSON values (undefined, functions, symbols,
29
+ * circular references) cause a TypeError so the caller can fail closed.
30
+ */
31
+ export function canonicalizeJson(value) {
32
+ const seen = new WeakSet();
33
+ function walk(v) {
34
+ if (v === null ||
35
+ typeof v === "boolean" ||
36
+ typeof v === "number" ||
37
+ typeof v === "string") {
38
+ return v;
39
+ }
40
+ if (typeof v === "undefined" ||
41
+ typeof v === "function" ||
42
+ typeof v === "symbol") {
43
+ throw new TypeError("Cannot canonicalize non-JSON value: " + typeof v);
44
+ }
45
+ if (Array.isArray(v)) {
46
+ return v.map(walk);
47
+ }
48
+ if (typeof v === "object") {
49
+ if (seen.has(v)) {
50
+ throw new TypeError("Cannot canonicalize circular reference");
51
+ }
52
+ seen.add(v);
53
+ const sortedKeys = Object.keys(v).sort();
54
+ const out = {};
55
+ for (const k of sortedKeys) {
56
+ out[k] = walk(v[k]);
57
+ }
58
+ return out;
59
+ }
60
+ throw new TypeError("Cannot canonicalize unexpected type: " + typeof v);
61
+ }
62
+ return JSON.stringify(walk(value));
63
+ }
64
+ /**
65
+ * Compute SHA-256 of canonical JSON, prefixed with `sha256:`.
66
+ */
67
+ export function canonicalHash(value) {
68
+ const canonical = canonicalizeJson(value);
69
+ const hash = createHash("sha256").update(canonical, "utf8").digest("hex");
70
+ return `sha256:${hash}`;
71
+ }
72
+ /**
73
+ * Decode base64url (no padding required).
74
+ */
75
+ function base64urlDecode(str) {
76
+ // Replace base64url chars with base64 chars and add padding
77
+ const base64 = str.replace(/-/g, "+").replace(/_/g, "/");
78
+ const padLen = (4 - (base64.length % 4)) % 4;
79
+ const padded = base64 + "=".repeat(padLen);
80
+ return Buffer.from(padded, "base64");
81
+ }
82
+ /**
83
+ * Parse an OTP envelope: `<base64url(payloadJson)>.<base64url(signature)>`.
84
+ * Returns the payload object and raw signature bytes.
85
+ */
86
+ export function parseOtp(otp) {
87
+ const parts = otp.split(".");
88
+ if (parts.length !== 2) {
89
+ throw new Error("OTP must contain exactly one '.' separator");
90
+ }
91
+ const payloadJson = base64urlDecode(parts[0]).toString("utf8");
92
+ const signature = base64urlDecode(parts[1]);
93
+ let payload;
94
+ try {
95
+ payload = JSON.parse(payloadJson);
96
+ }
97
+ catch {
98
+ throw new Error("OTP payload is not valid JSON");
99
+ }
100
+ if (typeof payload !== "object" ||
101
+ payload === null ||
102
+ !("v" in payload) ||
103
+ payload.v !== 1 ||
104
+ !("jti" in payload) ||
105
+ typeof payload.jti !== "string" ||
106
+ !("provider" in payload) ||
107
+ typeof payload.provider !== "string" ||
108
+ !("method" in payload) ||
109
+ typeof payload.method !== "string" ||
110
+ !("dotPath" in payload) ||
111
+ typeof payload.dotPath !== "string" ||
112
+ !("requestHash" in payload) ||
113
+ typeof payload.requestHash !== "string" ||
114
+ !("maxSpendUsd" in payload) ||
115
+ typeof payload.maxSpendUsd !== "number" ||
116
+ !("iat" in payload) ||
117
+ typeof payload.iat !== "number" ||
118
+ !("exp" in payload) ||
119
+ typeof payload.exp !== "number") {
120
+ throw new Error("OTP payload missing required fields");
121
+ }
122
+ return {
123
+ payload: payload,
124
+ signature,
125
+ };
126
+ }
127
+ /**
128
+ * Verify the Ed25519 signature of an OTP payload segment.
129
+ * `publicKey` is the PEM string read from the public key file.
130
+ */
131
+ export function verifyOtpSignature(payloadSegmentBase64url, signature, publicKeyPem) {
132
+ const key = createPublicKey(publicKeyPem);
133
+ const data = Buffer.from(payloadSegmentBase64url, "utf8");
134
+ return verify(null, data, key, signature);
135
+ }
136
+ /**
137
+ * Resolve the default replay ledger path.
138
+ */
139
+ function defaultLedgerPath() {
140
+ const xdg = process.env.XDG_STATE_HOME;
141
+ if (xdg) {
142
+ return join(xdg, "apicity", "paygate-used.jsonl");
143
+ }
144
+ return join(homedir(), ".local", "state", "apicity", "paygate-used.jsonl");
145
+ }
146
+ /**
147
+ * Check whether a jti has already been consumed.
148
+ *
149
+ * @param jti - The OTP jti to check
150
+ * @param ledgerPath - Optional override path; defaults to XDG_STATE_HOME or ~/.local/state
151
+ */
152
+ export function isJtiConsumed(jti, ledgerPath = defaultLedgerPath()) {
153
+ if (!existsSync(ledgerPath)) {
154
+ return false;
155
+ }
156
+ const content = readFileSync(ledgerPath, "utf8");
157
+ for (const line of content.split("\n")) {
158
+ const trimmed = line.trim();
159
+ if (!trimmed)
160
+ continue;
161
+ try {
162
+ const entry = JSON.parse(trimmed);
163
+ if (entry.jti === jti) {
164
+ return true;
165
+ }
166
+ }
167
+ catch {
168
+ // Skip malformed lines
169
+ }
170
+ }
171
+ return false;
172
+ }
173
+ /**
174
+ * Append a jti to the replay ledger.
175
+ *
176
+ * @param jti - The OTP jti to consume
177
+ * @param ledgerPath - Optional override path; defaults to XDG_STATE_HOME or ~/.local/state
178
+ */
179
+ export function consumeJti(jti, ledgerPath = defaultLedgerPath()) {
180
+ const dir = join(ledgerPath, "..");
181
+ if (!existsSync(dir)) {
182
+ mkdirSync(dir, { recursive: true });
183
+ }
184
+ const entry = JSON.stringify({
185
+ jti,
186
+ consumedAt: Math.floor(Date.now() / 1000),
187
+ });
188
+ appendFileSync(ledgerPath, entry + "\n", "utf8");
189
+ }
190
+ /**
191
+ * Load the Ed25519 public key PEM from the configured path.
192
+ */
193
+ function loadPublicKey() {
194
+ const path = process.env.APICITY_PAYGATE_PUBLIC_KEY_PATH;
195
+ if (!path) {
196
+ return undefined;
197
+ }
198
+ return readFileSync(path, "utf8");
199
+ }
200
+ /**
201
+ * Verify an OTP against the public key, checking signature, expiry,
202
+ * request binding, and replay.
203
+ */
204
+ function verifyOtp(provider, method, dotPath, payload, otp, publicKeyPem) {
205
+ let parsed;
206
+ try {
207
+ parsed = parseOtp(otp);
208
+ }
209
+ catch (e) {
210
+ throw new PayGateError(provider, method, dotPath, "otp-malformed", e instanceof Error ? e.message : "OTP is malformed");
211
+ }
212
+ const { payload: otpPayload, signature } = parsed;
213
+ const parts = otp.split(".");
214
+ const payloadSegment = parts[0];
215
+ const sigOk = verifyOtpSignature(payloadSegment, signature, publicKeyPem);
216
+ if (!sigOk) {
217
+ throw new PayGateError(provider, method, dotPath, "otp-invalid-signature", "OTP signature is invalid");
218
+ }
219
+ const now = Math.floor(Date.now() / 1000);
220
+ if (otpPayload.exp < now) {
221
+ throw new PayGateError(provider, method, dotPath, "otp-expired", `OTP expired at ${otpPayload.exp} (now is ${now})`);
222
+ }
223
+ if (otpPayload.provider !== provider ||
224
+ otpPayload.method !== method ||
225
+ otpPayload.dotPath !== dotPath) {
226
+ throw new PayGateError(provider, method, dotPath, "otp-mismatched-request", `OTP bound to ${otpPayload.provider} ${otpPayload.method} ${otpPayload.dotPath}, ` +
227
+ `but call is ${provider} ${method} ${dotPath}`);
228
+ }
229
+ const expectedHash = canonicalHash(payload);
230
+ if (otpPayload.requestHash !== expectedHash) {
231
+ throw new PayGateError(provider, method, dotPath, "otp-mismatched-request", `OTP request hash mismatch: expected ${expectedHash}, got ${otpPayload.requestHash}`);
232
+ }
233
+ if (isJtiConsumed(otpPayload.jti)) {
234
+ throw new PayGateError(provider, method, dotPath, "otp-replayed", `OTP jti ${otpPayload.jti} has already been consumed`);
235
+ }
236
+ return otpPayload;
237
+ }
238
+ /**
239
+ * Wrap a provider network dispatch with the OTP-based paid-endpoint gate.
240
+ *
241
+ * Free/unlisted endpoints return `dispatch()` immediately without OTP or
242
+ * pay gate configuration.
243
+ *
244
+ * Paid endpoints fail closed: if the pay gate is not configured, or the OTP
245
+ * is missing, invalid, expired, replayed, mismatched, or the cost exceeds the
246
+ * OTP's maxSpendUsd, the call throws before dispatch runs.
247
+ */
248
+ export async function dispatchWithPaidGate(provider, method, dotPath, payload, approval, dispatch) {
249
+ if (!isPaidEndpoint(provider, method, dotPath)) {
250
+ return dispatch();
251
+ }
252
+ const publicKeyPem = loadPublicKey();
253
+ if (!publicKeyPem) {
254
+ throw new PayGateError(provider, method, dotPath, "paygate-not-configured", "Pay gate is not configured: APICITY_PAYGATE_PUBLIC_KEY_PATH is not set");
255
+ }
256
+ if (!approval || !approval.otp) {
257
+ throw new PayGateError(provider, method, dotPath, "otp-missing", "Paid endpoint requires an OTP approval. Pass { otp: '...' }.");
258
+ }
259
+ const otpPayload = verifyOtp(provider, method, dotPath, payload, approval.otp, publicKeyPem);
260
+ const estimate = computeEstimate({
261
+ provider: provider,
262
+ payload,
263
+ });
264
+ if (estimate.warnings.length > 0) {
265
+ throw new SpendBoundError(provider, method, dotPath, otpPayload.maxSpendUsd, estimate.usd, `Endpoint ${provider} ${method} ${dotPath} spend cannot be bounded ` +
266
+ `from the payload: ${estimate.warnings.join("; ")}. ` +
267
+ `Pass an OTP with a higher maxSpendUsd, ` +
268
+ `or adjust the payload so the cost can be estimated.`);
269
+ }
270
+ if (estimate.usd > otpPayload.maxSpendUsd) {
271
+ throw new SpendBoundError(provider, method, dotPath, otpPayload.maxSpendUsd, estimate.usd, `Endpoint ${provider} ${method} ${dotPath} estimated cost ` +
272
+ `(${estimate.usd} USD) exceeds OTP maxSpendUsd (${otpPayload.maxSpendUsd} USD).`);
273
+ }
274
+ // Consume the OTP immediately before dispatch.
275
+ consumeJti(otpPayload.jti);
276
+ return dispatch();
277
+ }
278
+ //# sourceMappingURL=paygate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paygate.js","sourceRoot":"","sources":["../../src/paygate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AA0BnD;;;GAGG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,QAAQ,CAAS;IACjB,MAAM,CAAS;IACf,OAAO,CAAS;IAChB,IAAI,CAOM;IAEnB,YACE,QAAgB,EAChB,MAAc,EACd,OAAe,EACf,IAA0B,EAC1B,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,MAAM,IAAI,GAAG,IAAI,OAAO,EAAU,CAAC;IAEnC,SAAS,IAAI,CAAC,CAAU;QACtB,IACE,CAAC,KAAK,IAAI;YACV,OAAO,CAAC,KAAK,SAAS;YACtB,OAAO,CAAC,KAAK,QAAQ;YACrB,OAAO,CAAC,KAAK,QAAQ,EACrB,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IACE,OAAO,CAAC,KAAK,WAAW;YACxB,OAAO,CAAC,KAAK,UAAU;YACvB,OAAO,CAAC,KAAK,QAAQ,EACrB,CAAC;YACD,MAAM,IAAI,SAAS,CAAC,sCAAsC,GAAG,OAAO,CAAC,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1B,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChB,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAC;YAChE,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACZ,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACzC,MAAM,GAAG,GAA4B,EAAE,CAAC;YACxC,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;gBAC3B,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAE,CAA6B,CAAC,CAAC,CAAC,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,uCAAuC,GAAG,OAAO,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1E,OAAO,UAAU,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,GAAW;IAClC,4DAA4D;IAC5D,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3C,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW;IAIlC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;IAC7C,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IACD,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,KAAK,IAAI;QAChB,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC;QAChB,OAAmC,CAAC,CAAC,KAAK,CAAC;QAC5C,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC;QACnB,OAAQ,OAAmC,CAAC,GAAG,KAAK,QAAQ;QAC5D,CAAC,CAAC,UAAU,IAAI,OAAO,CAAC;QACxB,OAAQ,OAAmC,CAAC,QAAQ,KAAK,QAAQ;QACjE,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC;QACtB,OAAQ,OAAmC,CAAC,MAAM,KAAK,QAAQ;QAC/D,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC;QACvB,OAAQ,OAAmC,CAAC,OAAO,KAAK,QAAQ;QAChE,CAAC,CAAC,aAAa,IAAI,OAAO,CAAC;QAC3B,OAAQ,OAAmC,CAAC,WAAW,KAAK,QAAQ;QACpE,CAAC,CAAC,aAAa,IAAI,OAAO,CAAC;QAC3B,OAAQ,OAAmC,CAAC,WAAW,KAAK,QAAQ;QACpE,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC;QACnB,OAAQ,OAAmC,CAAC,GAAG,KAAK,QAAQ;QAC5D,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC;QACnB,OAAQ,OAAmC,CAAC,GAAG,KAAK,QAAQ,EAC5D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IACD,OAAO;QACL,OAAO,EAAE,OAA4B;QACrC,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,uBAA+B,EAC/B,SAAiB,EACjB,YAAoB;IAEpB,MAAM,GAAG,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;IAC1D,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB;IACxB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACvC,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,GAAW,EACX,aAAqB,iBAAiB,EAAE;IAExC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACjD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAqB,CAAC;YACtD,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;gBACtB,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uBAAuB;QACzB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,GAAW,EACX,aAAqB,iBAAiB,EAAE;IAExC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC;QAC3B,GAAG;QACH,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;KAC1C,CAAC,CAAC;IACH,cAAc,CAAC,UAAU,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,SAAS,aAAa;IACpB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC;IACzD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAChB,QAAgB,EAChB,MAAc,EACd,OAAe,EACf,OAAgC,EAChC,GAAW,EACX,YAAoB;IAEpB,IAAI,MAAyD,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,YAAY,CACpB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,eAAe,EACf,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CACpD,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAClD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;IAEjC,MAAM,KAAK,GAAG,kBAAkB,CAAC,cAAc,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAC1E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,YAAY,CACpB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,uBAAuB,EACvB,0BAA0B,CAC3B,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,IAAI,UAAU,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;QACzB,MAAM,IAAI,YAAY,CACpB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,aAAa,EACb,kBAAkB,UAAU,CAAC,GAAG,YAAY,GAAG,GAAG,CACnD,CAAC;IACJ,CAAC;IAED,IACE,UAAU,CAAC,QAAQ,KAAK,QAAQ;QAChC,UAAU,CAAC,MAAM,KAAK,MAAM;QAC5B,UAAU,CAAC,OAAO,KAAK,OAAO,EAC9B,CAAC;QACD,MAAM,IAAI,YAAY,CACpB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,wBAAwB,EACxB,gBAAgB,UAAU,CAAC,QAAQ,IAAI,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,OAAO,IAAI;YAChF,eAAe,QAAQ,IAAI,MAAM,IAAI,OAAO,EAAE,CACjD,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,UAAU,CAAC,WAAW,KAAK,YAAY,EAAE,CAAC;QAC5C,MAAM,IAAI,YAAY,CACpB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,wBAAwB,EACxB,uCAAuC,YAAY,SAAS,UAAU,CAAC,WAAW,EAAE,CACrF,CAAC;IACJ,CAAC;IAED,IAAI,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,YAAY,CACpB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,cAAc,EACd,WAAW,UAAU,CAAC,GAAG,4BAA4B,CACtD,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAgB,EAChB,MAAc,EACd,OAAe,EACf,OAAgC,EAChC,QAAqC,EACrC,QAA0B;IAE1B,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;QAC/C,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,MAAM,YAAY,GAAG,aAAa,EAAE,CAAC;IACrC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,YAAY,CACpB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,wBAAwB,EACxB,wEAAwE,CACzE,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;QAC/B,MAAM,IAAI,YAAY,CACpB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,aAAa,EACb,8DAA8D,CAC/D,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,SAAS,CAC1B,QAAQ,EACR,MAAM,EACN,OAAO,EACP,OAAO,EACP,QAAQ,CAAC,GAAG,EACZ,YAAY,CACb,CAAC;IAEF,MAAM,QAAQ,GAAG,eAAe,CAAC;QAC/B,QAAQ,EAAE,QAAuC;QACjD,OAAO;KACR,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,eAAe,CACvB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,UAAU,CAAC,WAAW,EACtB,QAAQ,CAAC,GAAG,EACZ,YAAY,QAAQ,IAAI,MAAM,IAAI,OAAO,2BAA2B;YAClE,qBAAqB,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACrD,yCAAyC;YACzC,qDAAqD,CACxD,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,GAAG,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,IAAI,eAAe,CACvB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,UAAU,CAAC,WAAW,EACtB,QAAQ,CAAC,GAAG,EACZ,YAAY,QAAQ,IAAI,MAAM,IAAI,OAAO,kBAAkB;YACzD,IAAI,QAAQ,CAAC,GAAG,kCAAkC,UAAU,CAAC,WAAW,QAAQ,CACnF,CAAC;IACJ,CAAC;IAED,+CAA+C;IAC/C,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAE3B,OAAO,QAAQ,EAAE,CAAC;AACpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"kie.d.ts","sourceRoot":"","sources":["../../../src/pricing/kie.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAkF5C,eAAO,MAAM,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAiQ5C,CAAC"}
1
+ {"version":3,"file":"kie.d.ts","sourceRoot":"","sources":["../../../src/pricing/kie.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAiG5C,eAAO,MAAM,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAqQ5C,CAAC"}
@@ -40,20 +40,34 @@ const flatGen = (perUnit, slug) => ({
40
40
  source: src(slug),
41
41
  });
42
42
  // Image entry tiered by input.resolution (e.g. "1K"|"2K"|"4K").
43
- const tieredImage = (rates, slug) => ({
43
+ // Optional `defaultResolution` is applied when the payload omits
44
+ // input.resolution (matches the upstream schema default).
45
+ const tieredImage = (rates, slug, defaultResolution) => ({
44
46
  kind: "perUnit",
45
47
  unit: "images",
46
48
  units: imageCount,
47
- select: [{ name: "resolution", pick: inputResolution }],
49
+ select: [
50
+ {
51
+ name: "resolution",
52
+ pick: (p) => asString(asObject(p.input)?.resolution) ?? defaultResolution,
53
+ },
54
+ ],
48
55
  rates,
49
56
  source: src(slug),
50
57
  });
51
58
  // Video entry tiered by input.resolution (grok-imagine, happyhorse).
52
- const tieredResolutionVideo = (rates, slug) => ({
59
+ // Optional `defaultResolution` is applied when the payload omits
60
+ // input.resolution (matches the upstream schema default).
61
+ const tieredResolutionVideo = (rates, slug, defaultResolution) => ({
53
62
  kind: "perUnit",
54
63
  unit: "seconds",
55
64
  units: seconds,
56
- select: [{ name: "resolution", pick: inputResolution }],
65
+ select: [
66
+ {
67
+ name: "resolution",
68
+ pick: (p) => asString(asObject(p.input)?.resolution) ?? defaultResolution,
69
+ },
70
+ ],
57
71
  rates,
58
72
  source: src(slug),
59
73
  });
@@ -221,12 +235,12 @@ export const kie = {
221
235
  // (nano-banana-2, gpt-image-2) require input.resolution; flat-rate
222
236
  // families (qwen2, seedream/5-lite) only need the model string.
223
237
  // wan/2-7-image accepts an `n` field for batch generation.
224
- "nano-banana-2": tieredImage({ "1K": 0.04, "2K": 0.06, "4K": 0.09 }, "google/nano-banana-2"),
238
+ "nano-banana-2": tieredImage({ "1K": 0.04, "2K": 0.06, "4K": 0.09 }, "google/nano-banana-2", "2K"),
225
239
  // nano-banana-pro: 1K and 2K share the $0.09 rate per the marketplace
226
240
  // ("1/2K"), 4K is $0.12.
227
- "nano-banana-pro": tieredImage({ "1K": 0.09, "2K": 0.09, "4K": 0.12 }, "google/nano-banana-pro"),
228
- "gpt-image-2-text-to-image": tieredImage({ "1K": 0.03, "2K": 0.05, "4K": 0.08 }, "openai/gpt-image-2"),
229
- "gpt-image-2-image-to-image": tieredImage({ "1K": 0.03, "2K": 0.05, "4K": 0.08 }, "openai/gpt-image-2"),
241
+ "nano-banana-pro": tieredImage({ "1K": 0.09, "2K": 0.09, "4K": 0.12 }, "google/nano-banana-pro", "2K"),
242
+ "gpt-image-2-text-to-image": tieredImage({ "1K": 0.03, "2K": 0.05, "4K": 0.08 }, "openai/gpt-image-2", "2K"),
243
+ "gpt-image-2-image-to-image": tieredImage({ "1K": 0.03, "2K": 0.05, "4K": 0.08 }, "openai/gpt-image-2", "2K"),
230
244
  "wan/2-7-image": flatImage(0.024, "alibaba/wan-2.7"),
231
245
  "wan/2-7-image-pro": flatImage(0.06, "alibaba/wan-2.7"),
232
246
  "qwen2/text-to-image": flatImage(0.028, "alibaba/qwen-image-2"),
@@ -1 +1 @@
1
- {"version":3,"file":"kie.js","sourceRoot":"","sources":["../../../src/pricing/kie.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kie.js","sourceRoot":"","sources":["../../../src/pricing/kie.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apicity/cost",
3
- "version": "0.2.0-alpha.0",
3
+ "version": "0.2.0-alpha.1",
4
4
  "description": "Pure-table cost & token estimation across @apicity providers — zero network calls, all rates bundled.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,6 +20,9 @@
20
20
  "types": "./dist/src/index.d.ts"
21
21
  }
22
22
  },
23
+ "bin": {
24
+ "apicity-paygate": "./dist/src/paygate-cli.js"
25
+ },
23
26
  "files": [
24
27
  "dist",
25
28
  "README.md",