letagentpay 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LetAgentPay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,208 @@
1
+ # letagentpay
2
+
3
+ TypeScript SDK for [LetAgentPay](https://letagentpay.com) — AI agent spending policy middleware. Set budgets, define spending policies, and control AI agent purchases.
4
+
5
+ **Zero dependencies.** Uses the built-in `fetch` API (Node.js 18+, Bun, Deno).
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install letagentpay
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { LetAgentPay } from "letagentpay";
17
+
18
+ const client = new LetAgentPay({ token: "agt_xxx" });
19
+
20
+ // Create a purchase request
21
+ const result = await client.requestPurchase({
22
+ amount: 15.0,
23
+ category: "api_calls",
24
+ description: "OpenAI GPT-4 call",
25
+ });
26
+ console.log(result.status); // "auto_approved" | "pending" | "rejected"
27
+
28
+ // Check budget
29
+ const budget = await client.checkBudget();
30
+ console.log(`Remaining: $${budget.remaining}`);
31
+ ```
32
+
33
+ ## API
34
+
35
+ ### `requestPurchase(options)`
36
+
37
+ Create a purchase request. The policy engine runs 8 deterministic checks (budget, category, per-request limit, schedule, daily/weekly/monthly limits).
38
+
39
+ ```typescript
40
+ const result = await client.requestPurchase({
41
+ amount: 25.0,
42
+ category: "software",
43
+ merchantName: "GitHub", // optional
44
+ description: "Copilot license", // optional
45
+ agentComment: "Monthly renewal", // optional, shown to reviewers
46
+ });
47
+
48
+ // result.status: "auto_approved" | "pending" | "rejected"
49
+ // result.requestId: "uuid"
50
+ // result.policyCheck: { passed: true, checks: [...] }
51
+ // result.budgetRemaining: 475.0 (only if auto_approved)
52
+ // result.expiresAt: "2026-..." (only if pending)
53
+ ```
54
+
55
+ ### `checkRequest(requestId)`
56
+
57
+ Check the status of a purchase request.
58
+
59
+ ```typescript
60
+ const status = await client.checkRequest("request-uuid");
61
+ // status.status: "auto_approved" | "pending" | "approved" | "rejected" | "expired"
62
+ ```
63
+
64
+ ### `confirmPurchase(requestId, options)`
65
+
66
+ Confirm a purchase after approval. Use this to report the actual amount spent.
67
+
68
+ ```typescript
69
+ await client.confirmPurchase("request-uuid", {
70
+ success: true,
71
+ actualAmount: 24.99, // optional, if different from requested
72
+ receiptUrl: "https://example.com/receipt", // optional
73
+ });
74
+ ```
75
+
76
+ ### `checkBudget()`
77
+
78
+ Get current budget breakdown.
79
+
80
+ ```typescript
81
+ const budget = await client.checkBudget();
82
+ // budget.budget: 500.0
83
+ // budget.spent: 125.5
84
+ // budget.held: 25.0 (reserved for pending requests)
85
+ // budget.remaining: 349.5
86
+ // budget.currency: "USD"
87
+ ```
88
+
89
+ ### `getPolicy()`
90
+
91
+ Get the current spending policy.
92
+
93
+ ```typescript
94
+ const policy = await client.getPolicy();
95
+ ```
96
+
97
+ ### `listCategories()`
98
+
99
+ List valid purchase categories.
100
+
101
+ ```typescript
102
+ const categories = await client.listCategories();
103
+ // ["groceries", "hardware", "software", "travel", ...]
104
+ ```
105
+
106
+ ### `myRequests(options?)`
107
+
108
+ List agent's purchase requests with optional filters.
109
+
110
+ ```typescript
111
+ const list = await client.myRequests({ status: "pending", limit: 10 });
112
+ // list.requests: [{ requestId, status, amount, category, ... }]
113
+ // list.total: 42
114
+ ```
115
+
116
+ ## guard()
117
+
118
+ Wrap an async function so it checks spending policy before executing:
119
+
120
+ ```typescript
121
+ import { guard } from "letagentpay";
122
+
123
+ const callOpenAI = guard(
124
+ async (prompt: string, cost: number) => {
125
+ // your OpenAI call here
126
+ return "response";
127
+ },
128
+ { token: "agt_xxx", category: "api_calls" }
129
+ );
130
+
131
+ // Automatically sends a purchase request for $0.03 before executing
132
+ await callOpenAI("Analyze this document", 0.03);
133
+ ```
134
+
135
+ With a fixed amount:
136
+
137
+ ```typescript
138
+ const sendEmail = guard(
139
+ async (to: string, body: string) => { /* ... */ },
140
+ { token: "agt_xxx", category: "email", amount: 0.01 }
141
+ );
142
+ ```
143
+
144
+ ## Self-Hosted
145
+
146
+ Point the SDK to your own LetAgentPay instance:
147
+
148
+ ```typescript
149
+ const client = new LetAgentPay({
150
+ token: "agt_xxx",
151
+ baseUrl: "http://localhost:8000/api/v1/agent-api",
152
+ });
153
+ ```
154
+
155
+ ## Environment Variables
156
+
157
+ ```bash
158
+ export LETAGENTPAY_TOKEN=agt_xxx
159
+ export LETAGENTPAY_BASE_URL=https://api.letagentpay.com/api/v1/agent-api # optional
160
+ ```
161
+
162
+ ```typescript
163
+ // Token is taken from LETAGENTPAY_TOKEN
164
+ const client = new LetAgentPay();
165
+ ```
166
+
167
+ ## Error Handling
168
+
169
+ ```typescript
170
+ import { LetAgentPay, LetAgentPayError } from "letagentpay";
171
+
172
+ try {
173
+ await client.requestPurchase({ amount: 100, category: "hardware" });
174
+ } catch (e) {
175
+ if (e instanceof LetAgentPayError) {
176
+ console.log(e.status); // 403
177
+ console.log(e.detail); // "Daily limit exceeded"
178
+ }
179
+ }
180
+ ```
181
+
182
+ ## Security Model
183
+
184
+ LetAgentPay uses **server-side cooperative enforcement**. When your agent calls `requestPurchase()`, the request is evaluated by the policy engine on the LetAgentPay server. The agent receives only the result (approved/denied/pending) and cannot:
185
+
186
+ - Modify its own policies (the `agt_` token grants access only to the Agent API)
187
+ - Override policy check results (they come from the server)
188
+ - Approve its own pending requests (only a human can do that via the dashboard)
189
+
190
+ This is a **cooperative model** — it protects against budget overruns, category violations, and scheduling mistakes by well-behaved agents. It does not sandbox a malicious agent that has direct access to payment APIs.
191
+
192
+ ### Best Practices
193
+
194
+ - **Don't give your agent raw payment credentials** (Stripe keys, credit card numbers). LetAgentPay should be the only spending channel
195
+ - Use `pending` + manual approval for high-value purchases
196
+ - Set per-request limits as an additional barrier
197
+ - Review the audit trail in the dashboard regularly
198
+
199
+ ## Documentation
200
+
201
+ - [LetAgentPay docs](https://letagentpay.com/developers)
202
+ - [Agent API Reference](https://letagentpay.com/developers)
203
+ - [Python SDK](https://github.com/LetAgentPay/letagentpay-python)
204
+ - [GitHub](https://github.com/LetAgentPay/letagentpay-js)
205
+
206
+ ## License
207
+
208
+ MIT
@@ -0,0 +1,168 @@
1
+ /** Individual policy check result. */
2
+ interface PolicyCheck {
3
+ rule: string;
4
+ result: "pass" | "fail";
5
+ detail: string;
6
+ }
7
+ /** Aggregated policy check result. */
8
+ interface PolicyResult {
9
+ passed: boolean;
10
+ checks: PolicyCheck[];
11
+ }
12
+ /** Response from creating a purchase request. */
13
+ interface PurchaseResult {
14
+ requestId: string;
15
+ status: "auto_approved" | "pending" | "rejected";
16
+ currency: string | null;
17
+ category: string | null;
18
+ originalCategory: string | null;
19
+ policyCheck: PolicyResult | null;
20
+ autoApproved: boolean;
21
+ budgetRemaining: number | null;
22
+ expiresAt: string | null;
23
+ }
24
+ /** Response from checking a purchase request status. */
25
+ interface RequestStatus {
26
+ requestId: string;
27
+ status: string;
28
+ amount: number;
29
+ category: string;
30
+ createdAt: string;
31
+ reviewedAt: string | null;
32
+ }
33
+ /** Response from confirming a purchase. */
34
+ interface ConfirmResult {
35
+ requestId: string;
36
+ status: "completed" | "failed";
37
+ actualAmount: number | null;
38
+ }
39
+ /** Current budget information. */
40
+ interface BudgetInfo {
41
+ budget: number;
42
+ spent: number;
43
+ held: number;
44
+ remaining: number;
45
+ currency: string | null;
46
+ }
47
+ /** Purchase request in a list response. */
48
+ interface PurchaseRequestInfo {
49
+ requestId: string;
50
+ status: string;
51
+ amount: number;
52
+ currency: string;
53
+ category: string;
54
+ merchant: string | null;
55
+ description: string | null;
56
+ createdAt: string | null;
57
+ reviewedAt: string | null;
58
+ expiresAt: string | null;
59
+ }
60
+ /** Paginated list of purchase requests. */
61
+ interface RequestList {
62
+ requests: PurchaseRequestInfo[];
63
+ total: number;
64
+ limit: number;
65
+ offset: number;
66
+ }
67
+ /** Options for creating a purchase request. */
68
+ interface PurchaseOptions {
69
+ amount: number;
70
+ category: string;
71
+ merchantName?: string;
72
+ description?: string;
73
+ agentComment?: string;
74
+ }
75
+ /** Options for confirming a purchase. */
76
+ interface ConfirmOptions {
77
+ success: boolean;
78
+ actualAmount?: number;
79
+ receiptUrl?: string;
80
+ }
81
+ /** Options for listing requests. */
82
+ interface ListRequestsOptions {
83
+ status?: string;
84
+ limit?: number;
85
+ offset?: number;
86
+ }
87
+ /** Client configuration. */
88
+ interface LetAgentPayConfig {
89
+ token?: string;
90
+ baseUrl?: string;
91
+ }
92
+
93
+ /**
94
+ * Client for the LetAgentPay Agent API.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * const client = new LetAgentPay({ token: "agt_..." });
99
+ * const result = await client.requestPurchase({
100
+ * amount: 25.00,
101
+ * category: "groceries",
102
+ * description: "Weekly supplies",
103
+ * });
104
+ * console.log(result.status); // "auto_approved" | "pending" | "rejected"
105
+ * ```
106
+ */
107
+ declare class LetAgentPay {
108
+ private readonly token;
109
+ private readonly baseUrl;
110
+ constructor(config?: LetAgentPayConfig);
111
+ private request;
112
+ /** Create a purchase request. */
113
+ requestPurchase(options: PurchaseOptions): Promise<PurchaseResult>;
114
+ /** Check the status of a purchase request. */
115
+ checkRequest(requestId: string): Promise<RequestStatus>;
116
+ /** Confirm a purchase result after approval. */
117
+ confirmPurchase(requestId: string, options: ConfirmOptions): Promise<ConfirmResult>;
118
+ /** Get current budget, spent, and remaining. */
119
+ checkBudget(): Promise<BudgetInfo>;
120
+ /** Get the current spending policy. */
121
+ getPolicy(): Promise<Record<string, unknown>>;
122
+ /** List valid purchase categories. */
123
+ listCategories(): Promise<string[]>;
124
+ /** List agent's purchase requests. */
125
+ myRequests(options?: ListRequestsOptions): Promise<RequestList>;
126
+ }
127
+
128
+ /** Error returned by the LetAgentPay API. */
129
+ declare class LetAgentPayError extends Error {
130
+ readonly status: number;
131
+ readonly detail: string;
132
+ constructor(status: number, detail: string);
133
+ }
134
+
135
+ /** Options for the guard wrapper. */
136
+ interface GuardOptions extends LetAgentPayConfig {
137
+ /** Existing client instance. Takes priority over token/baseUrl. */
138
+ client?: LetAgentPay;
139
+ /** Purchase category for the request. */
140
+ category?: string;
141
+ /** Fixed amount per call. If not set, must be passed to the guarded function. */
142
+ amount?: number;
143
+ /** Purchase description. */
144
+ description?: string;
145
+ /** Optional comment explaining the purchase. */
146
+ agentComment?: string;
147
+ }
148
+ /**
149
+ * Wrap an async function so it checks spending policy before executing.
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * const guardedBuy = guard(
154
+ * async (item: string, amount: number) => {
155
+ * return `Bought ${item} for $${amount}`;
156
+ * },
157
+ * { token: "agt_...", category: "groceries" }
158
+ * );
159
+ *
160
+ * // amount is extracted from the last numeric argument
161
+ * await guardedBuy("apples", 9.99);
162
+ * ```
163
+ */
164
+ declare function guard<TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn | Promise<TReturn>, options: GuardOptions & {
165
+ amount?: number;
166
+ }): (...args: TArgs) => Promise<TReturn>;
167
+
168
+ export { type BudgetInfo, type ConfirmOptions, type ConfirmResult, type GuardOptions, LetAgentPay, type LetAgentPayConfig, LetAgentPayError, type ListRequestsOptions, type PolicyCheck, type PolicyResult, type PurchaseOptions, type PurchaseRequestInfo, type PurchaseResult, type RequestList, type RequestStatus, guard };
@@ -0,0 +1,168 @@
1
+ /** Individual policy check result. */
2
+ interface PolicyCheck {
3
+ rule: string;
4
+ result: "pass" | "fail";
5
+ detail: string;
6
+ }
7
+ /** Aggregated policy check result. */
8
+ interface PolicyResult {
9
+ passed: boolean;
10
+ checks: PolicyCheck[];
11
+ }
12
+ /** Response from creating a purchase request. */
13
+ interface PurchaseResult {
14
+ requestId: string;
15
+ status: "auto_approved" | "pending" | "rejected";
16
+ currency: string | null;
17
+ category: string | null;
18
+ originalCategory: string | null;
19
+ policyCheck: PolicyResult | null;
20
+ autoApproved: boolean;
21
+ budgetRemaining: number | null;
22
+ expiresAt: string | null;
23
+ }
24
+ /** Response from checking a purchase request status. */
25
+ interface RequestStatus {
26
+ requestId: string;
27
+ status: string;
28
+ amount: number;
29
+ category: string;
30
+ createdAt: string;
31
+ reviewedAt: string | null;
32
+ }
33
+ /** Response from confirming a purchase. */
34
+ interface ConfirmResult {
35
+ requestId: string;
36
+ status: "completed" | "failed";
37
+ actualAmount: number | null;
38
+ }
39
+ /** Current budget information. */
40
+ interface BudgetInfo {
41
+ budget: number;
42
+ spent: number;
43
+ held: number;
44
+ remaining: number;
45
+ currency: string | null;
46
+ }
47
+ /** Purchase request in a list response. */
48
+ interface PurchaseRequestInfo {
49
+ requestId: string;
50
+ status: string;
51
+ amount: number;
52
+ currency: string;
53
+ category: string;
54
+ merchant: string | null;
55
+ description: string | null;
56
+ createdAt: string | null;
57
+ reviewedAt: string | null;
58
+ expiresAt: string | null;
59
+ }
60
+ /** Paginated list of purchase requests. */
61
+ interface RequestList {
62
+ requests: PurchaseRequestInfo[];
63
+ total: number;
64
+ limit: number;
65
+ offset: number;
66
+ }
67
+ /** Options for creating a purchase request. */
68
+ interface PurchaseOptions {
69
+ amount: number;
70
+ category: string;
71
+ merchantName?: string;
72
+ description?: string;
73
+ agentComment?: string;
74
+ }
75
+ /** Options for confirming a purchase. */
76
+ interface ConfirmOptions {
77
+ success: boolean;
78
+ actualAmount?: number;
79
+ receiptUrl?: string;
80
+ }
81
+ /** Options for listing requests. */
82
+ interface ListRequestsOptions {
83
+ status?: string;
84
+ limit?: number;
85
+ offset?: number;
86
+ }
87
+ /** Client configuration. */
88
+ interface LetAgentPayConfig {
89
+ token?: string;
90
+ baseUrl?: string;
91
+ }
92
+
93
+ /**
94
+ * Client for the LetAgentPay Agent API.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * const client = new LetAgentPay({ token: "agt_..." });
99
+ * const result = await client.requestPurchase({
100
+ * amount: 25.00,
101
+ * category: "groceries",
102
+ * description: "Weekly supplies",
103
+ * });
104
+ * console.log(result.status); // "auto_approved" | "pending" | "rejected"
105
+ * ```
106
+ */
107
+ declare class LetAgentPay {
108
+ private readonly token;
109
+ private readonly baseUrl;
110
+ constructor(config?: LetAgentPayConfig);
111
+ private request;
112
+ /** Create a purchase request. */
113
+ requestPurchase(options: PurchaseOptions): Promise<PurchaseResult>;
114
+ /** Check the status of a purchase request. */
115
+ checkRequest(requestId: string): Promise<RequestStatus>;
116
+ /** Confirm a purchase result after approval. */
117
+ confirmPurchase(requestId: string, options: ConfirmOptions): Promise<ConfirmResult>;
118
+ /** Get current budget, spent, and remaining. */
119
+ checkBudget(): Promise<BudgetInfo>;
120
+ /** Get the current spending policy. */
121
+ getPolicy(): Promise<Record<string, unknown>>;
122
+ /** List valid purchase categories. */
123
+ listCategories(): Promise<string[]>;
124
+ /** List agent's purchase requests. */
125
+ myRequests(options?: ListRequestsOptions): Promise<RequestList>;
126
+ }
127
+
128
+ /** Error returned by the LetAgentPay API. */
129
+ declare class LetAgentPayError extends Error {
130
+ readonly status: number;
131
+ readonly detail: string;
132
+ constructor(status: number, detail: string);
133
+ }
134
+
135
+ /** Options for the guard wrapper. */
136
+ interface GuardOptions extends LetAgentPayConfig {
137
+ /** Existing client instance. Takes priority over token/baseUrl. */
138
+ client?: LetAgentPay;
139
+ /** Purchase category for the request. */
140
+ category?: string;
141
+ /** Fixed amount per call. If not set, must be passed to the guarded function. */
142
+ amount?: number;
143
+ /** Purchase description. */
144
+ description?: string;
145
+ /** Optional comment explaining the purchase. */
146
+ agentComment?: string;
147
+ }
148
+ /**
149
+ * Wrap an async function so it checks spending policy before executing.
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * const guardedBuy = guard(
154
+ * async (item: string, amount: number) => {
155
+ * return `Bought ${item} for $${amount}`;
156
+ * },
157
+ * { token: "agt_...", category: "groceries" }
158
+ * );
159
+ *
160
+ * // amount is extracted from the last numeric argument
161
+ * await guardedBuy("apples", 9.99);
162
+ * ```
163
+ */
164
+ declare function guard<TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn | Promise<TReturn>, options: GuardOptions & {
165
+ amount?: number;
166
+ }): (...args: TArgs) => Promise<TReturn>;
167
+
168
+ export { type BudgetInfo, type ConfirmOptions, type ConfirmResult, type GuardOptions, LetAgentPay, type LetAgentPayConfig, LetAgentPayError, type ListRequestsOptions, type PolicyCheck, type PolicyResult, type PurchaseOptions, type PurchaseRequestInfo, type PurchaseResult, type RequestList, type RequestStatus, guard };
package/dist/index.js ADDED
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ LetAgentPay: () => LetAgentPay,
24
+ LetAgentPayError: () => LetAgentPayError,
25
+ guard: () => guard
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/errors.ts
30
+ var LetAgentPayError = class extends Error {
31
+ status;
32
+ detail;
33
+ constructor(status, detail) {
34
+ super(`[${status}] ${detail}`);
35
+ this.name = "LetAgentPayError";
36
+ this.status = status;
37
+ this.detail = detail;
38
+ }
39
+ };
40
+
41
+ // src/client.ts
42
+ var DEFAULT_BASE_URL = "https://api.letagentpay.com/api/v1/agent-api";
43
+ function getEnv(name) {
44
+ if (typeof process !== "undefined" && process.env) {
45
+ return process.env[name];
46
+ }
47
+ return void 0;
48
+ }
49
+ function parsePolicyCheck(data) {
50
+ return {
51
+ rule: data.rule,
52
+ result: data.result,
53
+ detail: data.detail
54
+ };
55
+ }
56
+ function parsePolicyResult(data) {
57
+ if (!data) return null;
58
+ const checks = data.checks || [];
59
+ return {
60
+ passed: data.passed,
61
+ checks: checks.map(parsePolicyCheck)
62
+ };
63
+ }
64
+ function parsePurchaseResult(data) {
65
+ return {
66
+ requestId: data.request_id,
67
+ status: data.status,
68
+ currency: data.currency ?? null,
69
+ category: data.category ?? null,
70
+ originalCategory: data.original_category ?? null,
71
+ policyCheck: parsePolicyResult(
72
+ data.policy_check ?? null
73
+ ),
74
+ autoApproved: data.auto_approved ?? false,
75
+ budgetRemaining: data.budget_remaining != null ? Number(data.budget_remaining) : null,
76
+ expiresAt: data.expires_at ?? null
77
+ };
78
+ }
79
+ function parseRequestStatus(data) {
80
+ return {
81
+ requestId: data.request_id,
82
+ status: data.status,
83
+ amount: Number(data.amount),
84
+ category: data.category,
85
+ createdAt: String(data.created_at),
86
+ reviewedAt: data.reviewed_at ? String(data.reviewed_at) : null
87
+ };
88
+ }
89
+ function parseConfirmResult(data) {
90
+ return {
91
+ requestId: data.request_id,
92
+ status: data.status,
93
+ actualAmount: data.actual_amount != null ? Number(data.actual_amount) : null
94
+ };
95
+ }
96
+ function parseBudgetInfo(data) {
97
+ return {
98
+ budget: Number(data.budget),
99
+ spent: Number(data.spent),
100
+ held: Number(data.held),
101
+ remaining: Number(data.remaining),
102
+ currency: data.currency ?? null
103
+ };
104
+ }
105
+ function parsePurchaseRequestInfo(data) {
106
+ return {
107
+ requestId: data.request_id,
108
+ status: data.status,
109
+ amount: Number(data.amount),
110
+ currency: data.currency ?? "USD",
111
+ category: data.category ?? "",
112
+ merchant: data.merchant ?? null,
113
+ description: data.description ?? null,
114
+ createdAt: data.created_at ? String(data.created_at) : null,
115
+ reviewedAt: data.reviewed_at ? String(data.reviewed_at) : null,
116
+ expiresAt: data.expires_at ? String(data.expires_at) : null
117
+ };
118
+ }
119
+ function parseRequestList(data) {
120
+ const requests = data.requests || [];
121
+ return {
122
+ requests: requests.map(parsePurchaseRequestInfo),
123
+ total: data.total ?? 0,
124
+ limit: data.limit ?? 20,
125
+ offset: data.offset ?? 0
126
+ };
127
+ }
128
+ var LetAgentPay = class {
129
+ token;
130
+ baseUrl;
131
+ constructor(config = {}) {
132
+ const resolvedToken = config.token ?? getEnv("LETAGENTPAY_TOKEN");
133
+ if (!resolvedToken) {
134
+ throw new Error(
135
+ "Token is required. Pass token in config or set LETAGENTPAY_TOKEN env var."
136
+ );
137
+ }
138
+ this.token = resolvedToken;
139
+ this.baseUrl = (config.baseUrl ?? getEnv("LETAGENTPAY_BASE_URL") ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
140
+ }
141
+ async request(method, path, options) {
142
+ let url = `${this.baseUrl}${path}`;
143
+ if (options?.params) {
144
+ const searchParams = new URLSearchParams(options.params);
145
+ url += `?${searchParams.toString()}`;
146
+ }
147
+ const response = await fetch(url, {
148
+ method,
149
+ headers: {
150
+ Authorization: `Bearer ${this.token}`,
151
+ "Content-Type": "application/json"
152
+ },
153
+ body: options?.body ? JSON.stringify(options.body) : void 0
154
+ });
155
+ const data = await response.json();
156
+ if (!response.ok) {
157
+ const detail = data.detail ?? response.statusText;
158
+ throw new LetAgentPayError(response.status, detail);
159
+ }
160
+ return data;
161
+ }
162
+ /** Create a purchase request. */
163
+ async requestPurchase(options) {
164
+ const body = {
165
+ amount: options.amount,
166
+ category: options.category
167
+ };
168
+ if (options.merchantName) body.merchant_name = options.merchantName;
169
+ if (options.description) body.description = options.description;
170
+ if (options.agentComment) body.agent_comment = options.agentComment;
171
+ const data = await this.request("POST", "/requests", { body });
172
+ return parsePurchaseResult(data);
173
+ }
174
+ /** Check the status of a purchase request. */
175
+ async checkRequest(requestId) {
176
+ const data = await this.request("GET", `/requests/${requestId}`);
177
+ return parseRequestStatus(data);
178
+ }
179
+ /** Confirm a purchase result after approval. */
180
+ async confirmPurchase(requestId, options) {
181
+ const body = { success: options.success };
182
+ if (options.actualAmount != null) body.actual_amount = options.actualAmount;
183
+ if (options.receiptUrl) body.receipt_url = options.receiptUrl;
184
+ const data = await this.request("POST", `/requests/${requestId}/confirm`, {
185
+ body
186
+ });
187
+ return parseConfirmResult(data);
188
+ }
189
+ /** Get current budget, spent, and remaining. */
190
+ async checkBudget() {
191
+ const data = await this.request("GET", "/budget");
192
+ return parseBudgetInfo(data);
193
+ }
194
+ /** Get the current spending policy. */
195
+ async getPolicy() {
196
+ return this.request("GET", "/policy");
197
+ }
198
+ /** List valid purchase categories. */
199
+ async listCategories() {
200
+ const data = await this.request("GET", "/categories");
201
+ return data.categories;
202
+ }
203
+ /** List agent's purchase requests. */
204
+ async myRequests(options = {}) {
205
+ const params = {};
206
+ if (options.status) params.status = options.status;
207
+ params.limit = String(options.limit ?? 20);
208
+ params.offset = String(options.offset ?? 0);
209
+ const data = await this.request("GET", "/requests", { params });
210
+ return parseRequestList(data);
211
+ }
212
+ };
213
+
214
+ // src/guard.ts
215
+ function guard(fn, options) {
216
+ return async (...args) => {
217
+ let resolvedAmount = options.amount;
218
+ if (resolvedAmount == null) {
219
+ for (const arg of args) {
220
+ if (typeof arg === "number") {
221
+ resolvedAmount = arg;
222
+ break;
223
+ }
224
+ }
225
+ }
226
+ if (resolvedAmount == null) {
227
+ throw new Error(
228
+ "guard: could not determine amount from arguments. Pass amount in guard options or as a numeric function argument."
229
+ );
230
+ }
231
+ const client = options.client ?? new LetAgentPay(options);
232
+ const result = await client.requestPurchase({
233
+ amount: resolvedAmount,
234
+ category: options.category ?? "other",
235
+ description: options.description ?? `Auto-guarded call to ${fn.name || "anonymous"}`,
236
+ agentComment: options.agentComment
237
+ });
238
+ if (result.status === "auto_approved" || result.status === "pending") {
239
+ if (result.status === "pending") {
240
+ throw new LetAgentPayError(
241
+ 403,
242
+ `Purchase request pending approval: ${result.requestId}`
243
+ );
244
+ }
245
+ return fn(...args);
246
+ }
247
+ throw new LetAgentPayError(
248
+ 403,
249
+ `Purchase request ${result.status}: ${result.requestId}`
250
+ );
251
+ };
252
+ }
253
+ // Annotate the CommonJS export names for ESM import in node:
254
+ 0 && (module.exports = {
255
+ LetAgentPay,
256
+ LetAgentPayError,
257
+ guard
258
+ });
259
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts","../src/guard.ts"],"sourcesContent":["export { LetAgentPay } from \"./client.js\";\nexport { LetAgentPayError } from \"./errors.js\";\nexport { guard } from \"./guard.js\";\nexport type { GuardOptions } from \"./guard.js\";\nexport type {\n BudgetInfo,\n ConfirmOptions,\n ConfirmResult,\n LetAgentPayConfig,\n ListRequestsOptions,\n PolicyCheck,\n PolicyResult,\n PurchaseOptions,\n PurchaseRequestInfo,\n PurchaseResult,\n RequestList,\n RequestStatus,\n} from \"./types.js\";\n","/** Error returned by the LetAgentPay API. */\nexport class LetAgentPayError extends Error {\n readonly status: number;\n readonly detail: string;\n\n constructor(status: number, detail: string) {\n super(`[${status}] ${detail}`);\n this.name = \"LetAgentPayError\";\n this.status = status;\n this.detail = detail;\n }\n}\n","import { LetAgentPayError } from \"./errors.js\";\nimport type {\n BudgetInfo,\n ConfirmOptions,\n ConfirmResult,\n LetAgentPayConfig,\n ListRequestsOptions,\n PolicyCheck,\n PolicyResult,\n PurchaseOptions,\n PurchaseRequestInfo,\n PurchaseResult,\n RequestList,\n RequestStatus,\n} from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.letagentpay.com/api/v1/agent-api\";\n\nfunction getEnv(name: string): string | undefined {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env[name];\n }\n return undefined;\n}\n\nfunction parsePolicyCheck(data: Record<string, unknown>): PolicyCheck {\n return {\n rule: data.rule as string,\n result: data.result as \"pass\" | \"fail\",\n detail: data.detail as string,\n };\n}\n\nfunction parsePolicyResult(\n data: Record<string, unknown> | null,\n): PolicyResult | null {\n if (!data) return null;\n const checks = (data.checks as Record<string, unknown>[]) || [];\n return {\n passed: data.passed as boolean,\n checks: checks.map(parsePolicyCheck),\n };\n}\n\nfunction parsePurchaseResult(data: Record<string, unknown>): PurchaseResult {\n return {\n requestId: data.request_id as string,\n status: data.status as PurchaseResult[\"status\"],\n currency: (data.currency as string) ?? null,\n category: (data.category as string) ?? null,\n originalCategory: (data.original_category as string) ?? null,\n policyCheck: parsePolicyResult(\n (data.policy_check as Record<string, unknown>) ?? null,\n ),\n autoApproved: (data.auto_approved as boolean) ?? false,\n budgetRemaining:\n data.budget_remaining != null ? Number(data.budget_remaining) : null,\n expiresAt: (data.expires_at as string) ?? null,\n };\n}\n\nfunction parseRequestStatus(data: Record<string, unknown>): RequestStatus {\n return {\n requestId: data.request_id as string,\n status: data.status as string,\n amount: Number(data.amount),\n category: data.category as string,\n createdAt: String(data.created_at),\n reviewedAt: data.reviewed_at ? String(data.reviewed_at) : null,\n };\n}\n\nfunction parseConfirmResult(data: Record<string, unknown>): ConfirmResult {\n return {\n requestId: data.request_id as string,\n status: data.status as ConfirmResult[\"status\"],\n actualAmount:\n data.actual_amount != null ? Number(data.actual_amount) : null,\n };\n}\n\nfunction parseBudgetInfo(data: Record<string, unknown>): BudgetInfo {\n return {\n budget: Number(data.budget),\n spent: Number(data.spent),\n held: Number(data.held),\n remaining: Number(data.remaining),\n currency: (data.currency as string) ?? null,\n };\n}\n\nfunction parsePurchaseRequestInfo(\n data: Record<string, unknown>,\n): PurchaseRequestInfo {\n return {\n requestId: data.request_id as string,\n status: data.status as string,\n amount: Number(data.amount),\n currency: (data.currency as string) ?? \"USD\",\n category: (data.category as string) ?? \"\",\n merchant: (data.merchant as string) ?? null,\n description: (data.description as string) ?? null,\n createdAt: data.created_at ? String(data.created_at) : null,\n reviewedAt: data.reviewed_at ? String(data.reviewed_at) : null,\n expiresAt: data.expires_at ? String(data.expires_at) : null,\n };\n}\n\nfunction parseRequestList(data: Record<string, unknown>): RequestList {\n const requests = (data.requests as Record<string, unknown>[]) || [];\n return {\n requests: requests.map(parsePurchaseRequestInfo),\n total: (data.total as number) ?? 0,\n limit: (data.limit as number) ?? 20,\n offset: (data.offset as number) ?? 0,\n };\n}\n\n/**\n * Client for the LetAgentPay Agent API.\n *\n * @example\n * ```ts\n * const client = new LetAgentPay({ token: \"agt_...\" });\n * const result = await client.requestPurchase({\n * amount: 25.00,\n * category: \"groceries\",\n * description: \"Weekly supplies\",\n * });\n * console.log(result.status); // \"auto_approved\" | \"pending\" | \"rejected\"\n * ```\n */\nexport class LetAgentPay {\n private readonly token: string;\n private readonly baseUrl: string;\n\n constructor(config: LetAgentPayConfig = {}) {\n const resolvedToken = config.token ?? getEnv(\"LETAGENTPAY_TOKEN\");\n if (!resolvedToken) {\n throw new Error(\n \"Token is required. Pass token in config or set LETAGENTPAY_TOKEN env var.\",\n );\n }\n\n this.token = resolvedToken;\n this.baseUrl = (\n config.baseUrl ??\n getEnv(\"LETAGENTPAY_BASE_URL\") ??\n DEFAULT_BASE_URL\n ).replace(/\\/+$/, \"\");\n }\n\n private async request(\n method: string,\n path: string,\n options?: { body?: unknown; params?: Record<string, string> },\n ): Promise<Record<string, unknown>> {\n let url = `${this.baseUrl}${path}`;\n\n if (options?.params) {\n const searchParams = new URLSearchParams(options.params);\n url += `?${searchParams.toString()}`;\n }\n\n const response = await fetch(url, {\n method,\n headers: {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n },\n body: options?.body ? JSON.stringify(options.body) : undefined,\n });\n\n const data = (await response.json()) as Record<string, unknown>;\n\n if (!response.ok) {\n const detail = (data.detail as string) ?? response.statusText;\n throw new LetAgentPayError(response.status, detail);\n }\n\n return data;\n }\n\n /** Create a purchase request. */\n async requestPurchase(options: PurchaseOptions): Promise<PurchaseResult> {\n const body: Record<string, unknown> = {\n amount: options.amount,\n category: options.category,\n };\n if (options.merchantName) body.merchant_name = options.merchantName;\n if (options.description) body.description = options.description;\n if (options.agentComment) body.agent_comment = options.agentComment;\n\n const data = await this.request(\"POST\", \"/requests\", { body });\n return parsePurchaseResult(data);\n }\n\n /** Check the status of a purchase request. */\n async checkRequest(requestId: string): Promise<RequestStatus> {\n const data = await this.request(\"GET\", `/requests/${requestId}`);\n return parseRequestStatus(data);\n }\n\n /** Confirm a purchase result after approval. */\n async confirmPurchase(\n requestId: string,\n options: ConfirmOptions,\n ): Promise<ConfirmResult> {\n const body: Record<string, unknown> = { success: options.success };\n if (options.actualAmount != null) body.actual_amount = options.actualAmount;\n if (options.receiptUrl) body.receipt_url = options.receiptUrl;\n\n const data = await this.request(\"POST\", `/requests/${requestId}/confirm`, {\n body,\n });\n return parseConfirmResult(data);\n }\n\n /** Get current budget, spent, and remaining. */\n async checkBudget(): Promise<BudgetInfo> {\n const data = await this.request(\"GET\", \"/budget\");\n return parseBudgetInfo(data);\n }\n\n /** Get the current spending policy. */\n async getPolicy(): Promise<Record<string, unknown>> {\n return this.request(\"GET\", \"/policy\");\n }\n\n /** List valid purchase categories. */\n async listCategories(): Promise<string[]> {\n const data = await this.request(\"GET\", \"/categories\");\n return data.categories as string[];\n }\n\n /** List agent's purchase requests. */\n async myRequests(options: ListRequestsOptions = {}): Promise<RequestList> {\n const params: Record<string, string> = {};\n if (options.status) params.status = options.status;\n params.limit = String(options.limit ?? 20);\n params.offset = String(options.offset ?? 0);\n\n const data = await this.request(\"GET\", \"/requests\", { params });\n return parseRequestList(data);\n }\n}\n","import { LetAgentPay } from \"./client.js\";\nimport { LetAgentPayError } from \"./errors.js\";\nimport type { LetAgentPayConfig } from \"./types.js\";\n\n/** Options for the guard wrapper. */\nexport interface GuardOptions extends LetAgentPayConfig {\n /** Existing client instance. Takes priority over token/baseUrl. */\n client?: LetAgentPay;\n /** Purchase category for the request. */\n category?: string;\n /** Fixed amount per call. If not set, must be passed to the guarded function. */\n amount?: number;\n /** Purchase description. */\n description?: string;\n /** Optional comment explaining the purchase. */\n agentComment?: string;\n}\n\n/**\n * Wrap an async function so it checks spending policy before executing.\n *\n * @example\n * ```ts\n * const guardedBuy = guard(\n * async (item: string, amount: number) => {\n * return `Bought ${item} for $${amount}`;\n * },\n * { token: \"agt_...\", category: \"groceries\" }\n * );\n *\n * // amount is extracted from the last numeric argument\n * await guardedBuy(\"apples\", 9.99);\n * ```\n */\nexport function guard<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn | Promise<TReturn>,\n options: GuardOptions & { amount?: number },\n): (...args: TArgs) => Promise<TReturn> {\n return async (...args: TArgs): Promise<TReturn> => {\n let resolvedAmount = options.amount;\n if (resolvedAmount == null) {\n // Try to find a numeric argument (first one)\n for (const arg of args) {\n if (typeof arg === \"number\") {\n resolvedAmount = arg;\n break;\n }\n }\n }\n\n if (resolvedAmount == null) {\n throw new Error(\n \"guard: could not determine amount from arguments. \" +\n \"Pass amount in guard options or as a numeric function argument.\",\n );\n }\n\n const client = options.client ?? new LetAgentPay(options);\n\n const result = await client.requestPurchase({\n amount: resolvedAmount,\n category: options.category ?? \"other\",\n description:\n options.description ?? `Auto-guarded call to ${fn.name || \"anonymous\"}`,\n agentComment: options.agentComment,\n });\n\n if (result.status === \"auto_approved\" || result.status === \"pending\") {\n if (result.status === \"pending\") {\n throw new LetAgentPayError(\n 403,\n `Purchase request pending approval: ${result.requestId}`,\n );\n }\n return fn(...args);\n }\n\n throw new LetAgentPayError(\n 403,\n `Purchase request ${result.status}: ${result.requestId}`,\n );\n };\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,230 @@
1
+ // src/errors.ts
2
+ var LetAgentPayError = class extends Error {
3
+ status;
4
+ detail;
5
+ constructor(status, detail) {
6
+ super(`[${status}] ${detail}`);
7
+ this.name = "LetAgentPayError";
8
+ this.status = status;
9
+ this.detail = detail;
10
+ }
11
+ };
12
+
13
+ // src/client.ts
14
+ var DEFAULT_BASE_URL = "https://api.letagentpay.com/api/v1/agent-api";
15
+ function getEnv(name) {
16
+ if (typeof process !== "undefined" && process.env) {
17
+ return process.env[name];
18
+ }
19
+ return void 0;
20
+ }
21
+ function parsePolicyCheck(data) {
22
+ return {
23
+ rule: data.rule,
24
+ result: data.result,
25
+ detail: data.detail
26
+ };
27
+ }
28
+ function parsePolicyResult(data) {
29
+ if (!data) return null;
30
+ const checks = data.checks || [];
31
+ return {
32
+ passed: data.passed,
33
+ checks: checks.map(parsePolicyCheck)
34
+ };
35
+ }
36
+ function parsePurchaseResult(data) {
37
+ return {
38
+ requestId: data.request_id,
39
+ status: data.status,
40
+ currency: data.currency ?? null,
41
+ category: data.category ?? null,
42
+ originalCategory: data.original_category ?? null,
43
+ policyCheck: parsePolicyResult(
44
+ data.policy_check ?? null
45
+ ),
46
+ autoApproved: data.auto_approved ?? false,
47
+ budgetRemaining: data.budget_remaining != null ? Number(data.budget_remaining) : null,
48
+ expiresAt: data.expires_at ?? null
49
+ };
50
+ }
51
+ function parseRequestStatus(data) {
52
+ return {
53
+ requestId: data.request_id,
54
+ status: data.status,
55
+ amount: Number(data.amount),
56
+ category: data.category,
57
+ createdAt: String(data.created_at),
58
+ reviewedAt: data.reviewed_at ? String(data.reviewed_at) : null
59
+ };
60
+ }
61
+ function parseConfirmResult(data) {
62
+ return {
63
+ requestId: data.request_id,
64
+ status: data.status,
65
+ actualAmount: data.actual_amount != null ? Number(data.actual_amount) : null
66
+ };
67
+ }
68
+ function parseBudgetInfo(data) {
69
+ return {
70
+ budget: Number(data.budget),
71
+ spent: Number(data.spent),
72
+ held: Number(data.held),
73
+ remaining: Number(data.remaining),
74
+ currency: data.currency ?? null
75
+ };
76
+ }
77
+ function parsePurchaseRequestInfo(data) {
78
+ return {
79
+ requestId: data.request_id,
80
+ status: data.status,
81
+ amount: Number(data.amount),
82
+ currency: data.currency ?? "USD",
83
+ category: data.category ?? "",
84
+ merchant: data.merchant ?? null,
85
+ description: data.description ?? null,
86
+ createdAt: data.created_at ? String(data.created_at) : null,
87
+ reviewedAt: data.reviewed_at ? String(data.reviewed_at) : null,
88
+ expiresAt: data.expires_at ? String(data.expires_at) : null
89
+ };
90
+ }
91
+ function parseRequestList(data) {
92
+ const requests = data.requests || [];
93
+ return {
94
+ requests: requests.map(parsePurchaseRequestInfo),
95
+ total: data.total ?? 0,
96
+ limit: data.limit ?? 20,
97
+ offset: data.offset ?? 0
98
+ };
99
+ }
100
+ var LetAgentPay = class {
101
+ token;
102
+ baseUrl;
103
+ constructor(config = {}) {
104
+ const resolvedToken = config.token ?? getEnv("LETAGENTPAY_TOKEN");
105
+ if (!resolvedToken) {
106
+ throw new Error(
107
+ "Token is required. Pass token in config or set LETAGENTPAY_TOKEN env var."
108
+ );
109
+ }
110
+ this.token = resolvedToken;
111
+ this.baseUrl = (config.baseUrl ?? getEnv("LETAGENTPAY_BASE_URL") ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
112
+ }
113
+ async request(method, path, options) {
114
+ let url = `${this.baseUrl}${path}`;
115
+ if (options?.params) {
116
+ const searchParams = new URLSearchParams(options.params);
117
+ url += `?${searchParams.toString()}`;
118
+ }
119
+ const response = await fetch(url, {
120
+ method,
121
+ headers: {
122
+ Authorization: `Bearer ${this.token}`,
123
+ "Content-Type": "application/json"
124
+ },
125
+ body: options?.body ? JSON.stringify(options.body) : void 0
126
+ });
127
+ const data = await response.json();
128
+ if (!response.ok) {
129
+ const detail = data.detail ?? response.statusText;
130
+ throw new LetAgentPayError(response.status, detail);
131
+ }
132
+ return data;
133
+ }
134
+ /** Create a purchase request. */
135
+ async requestPurchase(options) {
136
+ const body = {
137
+ amount: options.amount,
138
+ category: options.category
139
+ };
140
+ if (options.merchantName) body.merchant_name = options.merchantName;
141
+ if (options.description) body.description = options.description;
142
+ if (options.agentComment) body.agent_comment = options.agentComment;
143
+ const data = await this.request("POST", "/requests", { body });
144
+ return parsePurchaseResult(data);
145
+ }
146
+ /** Check the status of a purchase request. */
147
+ async checkRequest(requestId) {
148
+ const data = await this.request("GET", `/requests/${requestId}`);
149
+ return parseRequestStatus(data);
150
+ }
151
+ /** Confirm a purchase result after approval. */
152
+ async confirmPurchase(requestId, options) {
153
+ const body = { success: options.success };
154
+ if (options.actualAmount != null) body.actual_amount = options.actualAmount;
155
+ if (options.receiptUrl) body.receipt_url = options.receiptUrl;
156
+ const data = await this.request("POST", `/requests/${requestId}/confirm`, {
157
+ body
158
+ });
159
+ return parseConfirmResult(data);
160
+ }
161
+ /** Get current budget, spent, and remaining. */
162
+ async checkBudget() {
163
+ const data = await this.request("GET", "/budget");
164
+ return parseBudgetInfo(data);
165
+ }
166
+ /** Get the current spending policy. */
167
+ async getPolicy() {
168
+ return this.request("GET", "/policy");
169
+ }
170
+ /** List valid purchase categories. */
171
+ async listCategories() {
172
+ const data = await this.request("GET", "/categories");
173
+ return data.categories;
174
+ }
175
+ /** List agent's purchase requests. */
176
+ async myRequests(options = {}) {
177
+ const params = {};
178
+ if (options.status) params.status = options.status;
179
+ params.limit = String(options.limit ?? 20);
180
+ params.offset = String(options.offset ?? 0);
181
+ const data = await this.request("GET", "/requests", { params });
182
+ return parseRequestList(data);
183
+ }
184
+ };
185
+
186
+ // src/guard.ts
187
+ function guard(fn, options) {
188
+ return async (...args) => {
189
+ let resolvedAmount = options.amount;
190
+ if (resolvedAmount == null) {
191
+ for (const arg of args) {
192
+ if (typeof arg === "number") {
193
+ resolvedAmount = arg;
194
+ break;
195
+ }
196
+ }
197
+ }
198
+ if (resolvedAmount == null) {
199
+ throw new Error(
200
+ "guard: could not determine amount from arguments. Pass amount in guard options or as a numeric function argument."
201
+ );
202
+ }
203
+ const client = options.client ?? new LetAgentPay(options);
204
+ const result = await client.requestPurchase({
205
+ amount: resolvedAmount,
206
+ category: options.category ?? "other",
207
+ description: options.description ?? `Auto-guarded call to ${fn.name || "anonymous"}`,
208
+ agentComment: options.agentComment
209
+ });
210
+ if (result.status === "auto_approved" || result.status === "pending") {
211
+ if (result.status === "pending") {
212
+ throw new LetAgentPayError(
213
+ 403,
214
+ `Purchase request pending approval: ${result.requestId}`
215
+ );
216
+ }
217
+ return fn(...args);
218
+ }
219
+ throw new LetAgentPayError(
220
+ 403,
221
+ `Purchase request ${result.status}: ${result.requestId}`
222
+ );
223
+ };
224
+ }
225
+ export {
226
+ LetAgentPay,
227
+ LetAgentPayError,
228
+ guard
229
+ };
230
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/guard.ts"],"sourcesContent":["/** Error returned by the LetAgentPay API. */\nexport class LetAgentPayError extends Error {\n readonly status: number;\n readonly detail: string;\n\n constructor(status: number, detail: string) {\n super(`[${status}] ${detail}`);\n this.name = \"LetAgentPayError\";\n this.status = status;\n this.detail = detail;\n }\n}\n","import { LetAgentPayError } from \"./errors.js\";\nimport type {\n BudgetInfo,\n ConfirmOptions,\n ConfirmResult,\n LetAgentPayConfig,\n ListRequestsOptions,\n PolicyCheck,\n PolicyResult,\n PurchaseOptions,\n PurchaseRequestInfo,\n PurchaseResult,\n RequestList,\n RequestStatus,\n} from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.letagentpay.com/api/v1/agent-api\";\n\nfunction getEnv(name: string): string | undefined {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env[name];\n }\n return undefined;\n}\n\nfunction parsePolicyCheck(data: Record<string, unknown>): PolicyCheck {\n return {\n rule: data.rule as string,\n result: data.result as \"pass\" | \"fail\",\n detail: data.detail as string,\n };\n}\n\nfunction parsePolicyResult(\n data: Record<string, unknown> | null,\n): PolicyResult | null {\n if (!data) return null;\n const checks = (data.checks as Record<string, unknown>[]) || [];\n return {\n passed: data.passed as boolean,\n checks: checks.map(parsePolicyCheck),\n };\n}\n\nfunction parsePurchaseResult(data: Record<string, unknown>): PurchaseResult {\n return {\n requestId: data.request_id as string,\n status: data.status as PurchaseResult[\"status\"],\n currency: (data.currency as string) ?? null,\n category: (data.category as string) ?? null,\n originalCategory: (data.original_category as string) ?? null,\n policyCheck: parsePolicyResult(\n (data.policy_check as Record<string, unknown>) ?? null,\n ),\n autoApproved: (data.auto_approved as boolean) ?? false,\n budgetRemaining:\n data.budget_remaining != null ? Number(data.budget_remaining) : null,\n expiresAt: (data.expires_at as string) ?? null,\n };\n}\n\nfunction parseRequestStatus(data: Record<string, unknown>): RequestStatus {\n return {\n requestId: data.request_id as string,\n status: data.status as string,\n amount: Number(data.amount),\n category: data.category as string,\n createdAt: String(data.created_at),\n reviewedAt: data.reviewed_at ? String(data.reviewed_at) : null,\n };\n}\n\nfunction parseConfirmResult(data: Record<string, unknown>): ConfirmResult {\n return {\n requestId: data.request_id as string,\n status: data.status as ConfirmResult[\"status\"],\n actualAmount:\n data.actual_amount != null ? Number(data.actual_amount) : null,\n };\n}\n\nfunction parseBudgetInfo(data: Record<string, unknown>): BudgetInfo {\n return {\n budget: Number(data.budget),\n spent: Number(data.spent),\n held: Number(data.held),\n remaining: Number(data.remaining),\n currency: (data.currency as string) ?? null,\n };\n}\n\nfunction parsePurchaseRequestInfo(\n data: Record<string, unknown>,\n): PurchaseRequestInfo {\n return {\n requestId: data.request_id as string,\n status: data.status as string,\n amount: Number(data.amount),\n currency: (data.currency as string) ?? \"USD\",\n category: (data.category as string) ?? \"\",\n merchant: (data.merchant as string) ?? null,\n description: (data.description as string) ?? null,\n createdAt: data.created_at ? String(data.created_at) : null,\n reviewedAt: data.reviewed_at ? String(data.reviewed_at) : null,\n expiresAt: data.expires_at ? String(data.expires_at) : null,\n };\n}\n\nfunction parseRequestList(data: Record<string, unknown>): RequestList {\n const requests = (data.requests as Record<string, unknown>[]) || [];\n return {\n requests: requests.map(parsePurchaseRequestInfo),\n total: (data.total as number) ?? 0,\n limit: (data.limit as number) ?? 20,\n offset: (data.offset as number) ?? 0,\n };\n}\n\n/**\n * Client for the LetAgentPay Agent API.\n *\n * @example\n * ```ts\n * const client = new LetAgentPay({ token: \"agt_...\" });\n * const result = await client.requestPurchase({\n * amount: 25.00,\n * category: \"groceries\",\n * description: \"Weekly supplies\",\n * });\n * console.log(result.status); // \"auto_approved\" | \"pending\" | \"rejected\"\n * ```\n */\nexport class LetAgentPay {\n private readonly token: string;\n private readonly baseUrl: string;\n\n constructor(config: LetAgentPayConfig = {}) {\n const resolvedToken = config.token ?? getEnv(\"LETAGENTPAY_TOKEN\");\n if (!resolvedToken) {\n throw new Error(\n \"Token is required. Pass token in config or set LETAGENTPAY_TOKEN env var.\",\n );\n }\n\n this.token = resolvedToken;\n this.baseUrl = (\n config.baseUrl ??\n getEnv(\"LETAGENTPAY_BASE_URL\") ??\n DEFAULT_BASE_URL\n ).replace(/\\/+$/, \"\");\n }\n\n private async request(\n method: string,\n path: string,\n options?: { body?: unknown; params?: Record<string, string> },\n ): Promise<Record<string, unknown>> {\n let url = `${this.baseUrl}${path}`;\n\n if (options?.params) {\n const searchParams = new URLSearchParams(options.params);\n url += `?${searchParams.toString()}`;\n }\n\n const response = await fetch(url, {\n method,\n headers: {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n },\n body: options?.body ? JSON.stringify(options.body) : undefined,\n });\n\n const data = (await response.json()) as Record<string, unknown>;\n\n if (!response.ok) {\n const detail = (data.detail as string) ?? response.statusText;\n throw new LetAgentPayError(response.status, detail);\n }\n\n return data;\n }\n\n /** Create a purchase request. */\n async requestPurchase(options: PurchaseOptions): Promise<PurchaseResult> {\n const body: Record<string, unknown> = {\n amount: options.amount,\n category: options.category,\n };\n if (options.merchantName) body.merchant_name = options.merchantName;\n if (options.description) body.description = options.description;\n if (options.agentComment) body.agent_comment = options.agentComment;\n\n const data = await this.request(\"POST\", \"/requests\", { body });\n return parsePurchaseResult(data);\n }\n\n /** Check the status of a purchase request. */\n async checkRequest(requestId: string): Promise<RequestStatus> {\n const data = await this.request(\"GET\", `/requests/${requestId}`);\n return parseRequestStatus(data);\n }\n\n /** Confirm a purchase result after approval. */\n async confirmPurchase(\n requestId: string,\n options: ConfirmOptions,\n ): Promise<ConfirmResult> {\n const body: Record<string, unknown> = { success: options.success };\n if (options.actualAmount != null) body.actual_amount = options.actualAmount;\n if (options.receiptUrl) body.receipt_url = options.receiptUrl;\n\n const data = await this.request(\"POST\", `/requests/${requestId}/confirm`, {\n body,\n });\n return parseConfirmResult(data);\n }\n\n /** Get current budget, spent, and remaining. */\n async checkBudget(): Promise<BudgetInfo> {\n const data = await this.request(\"GET\", \"/budget\");\n return parseBudgetInfo(data);\n }\n\n /** Get the current spending policy. */\n async getPolicy(): Promise<Record<string, unknown>> {\n return this.request(\"GET\", \"/policy\");\n }\n\n /** List valid purchase categories. */\n async listCategories(): Promise<string[]> {\n const data = await this.request(\"GET\", \"/categories\");\n return data.categories as string[];\n }\n\n /** List agent's purchase requests. */\n async myRequests(options: ListRequestsOptions = {}): Promise<RequestList> {\n const params: Record<string, string> = {};\n if (options.status) params.status = options.status;\n params.limit = String(options.limit ?? 20);\n params.offset = String(options.offset ?? 0);\n\n const data = await this.request(\"GET\", \"/requests\", { params });\n return parseRequestList(data);\n }\n}\n","import { LetAgentPay } from \"./client.js\";\nimport { LetAgentPayError } from \"./errors.js\";\nimport type { LetAgentPayConfig } from \"./types.js\";\n\n/** Options for the guard wrapper. */\nexport interface GuardOptions extends LetAgentPayConfig {\n /** Existing client instance. Takes priority over token/baseUrl. */\n client?: LetAgentPay;\n /** Purchase category for the request. */\n category?: string;\n /** Fixed amount per call. If not set, must be passed to the guarded function. */\n amount?: number;\n /** Purchase description. */\n description?: string;\n /** Optional comment explaining the purchase. */\n agentComment?: string;\n}\n\n/**\n * Wrap an async function so it checks spending policy before executing.\n *\n * @example\n * ```ts\n * const guardedBuy = guard(\n * async (item: string, amount: number) => {\n * return `Bought ${item} for $${amount}`;\n * },\n * { token: \"agt_...\", category: \"groceries\" }\n * );\n *\n * // amount is extracted from the last numeric argument\n * await guardedBuy(\"apples\", 9.99);\n * ```\n */\nexport function guard<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn | Promise<TReturn>,\n options: GuardOptions & { amount?: number },\n): (...args: TArgs) => Promise<TReturn> {\n return async (...args: TArgs): Promise<TReturn> => {\n let resolvedAmount = options.amount;\n if (resolvedAmount == null) {\n // Try to find a numeric argument (first one)\n for (const arg of args) {\n if (typeof arg === \"number\") {\n resolvedAmount = arg;\n break;\n }\n }\n }\n\n if (resolvedAmount == null) {\n throw new Error(\n \"guard: could not determine amount from arguments. \" +\n \"Pass amount in guard options or as a numeric function argument.\",\n );\n }\n\n const client = options.client ?? new LetAgentPay(options);\n\n const result = await client.requestPurchase({\n amount: resolvedAmount,\n category: options.category ?? \"other\",\n description:\n options.description ?? `Auto-guarded call to ${fn.name || \"anonymous\"}`,\n agentComment: options.agentComment,\n });\n\n if (result.status === \"auto_approved\" || result.status === \"pending\") {\n if (result.status === \"pending\") {\n throw new LetAgentPayError(\n 403,\n `Purchase request pending approval: ${result.requestId}`,\n );\n }\n return fn(...args);\n }\n\n throw new LetAgentPayError(\n 403,\n `Purchase request ${result.status}: ${result.requestId}`,\n );\n };\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "letagentpay",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for LetAgentPay — AI agent spending policy middleware",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "test": "vitest run",
21
+ "test:watch": "vitest",
22
+ "lint": "tsc --noEmit",
23
+ "prepublishOnly": "npm run build"
24
+ },
25
+ "keywords": [
26
+ "ai",
27
+ "agent",
28
+ "spending",
29
+ "policy",
30
+ "budget",
31
+ "llm",
32
+ "openclaw",
33
+ "letagentpay"
34
+ ],
35
+ "author": "LetAgentPay <hello@letagentpay.com>",
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/LetAgentPay/letagentpay-js"
40
+ },
41
+ "homepage": "https://letagentpay.com",
42
+ "bugs": {
43
+ "url": "https://github.com/LetAgentPay/letagentpay-js/issues"
44
+ },
45
+ "engines": {
46
+ "node": ">=18"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^25.5.2",
50
+ "tsup": "^8.0.0",
51
+ "typescript": "^5.5.0",
52
+ "vitest": "^3.0.0"
53
+ }
54
+ }