@haven_ai/sdk 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.
@@ -0,0 +1,322 @@
1
+ interface HavenClientConfig {
2
+ /** Haven API key (sk_agent_xxx) */
3
+ apiKey: string;
4
+ /** Agent's delegate EOA private key. If provided, the SDK handles signing automatically. */
5
+ delegateKey?: string;
6
+ /** Haven API base URL (default: http://localhost:3001) */
7
+ baseUrl?: string;
8
+ /** Timeout in ms for individual HTTP requests (default: 30000) */
9
+ requestTimeout?: number;
10
+ /** Timeout in ms when polling for tx confirmation (default: 90000) */
11
+ confirmationTimeout?: number;
12
+ /** Polling interval in ms when waiting for confirmation (default: 3000) */
13
+ pollingInterval?: number;
14
+ }
15
+ interface PaymentRequest {
16
+ /** Token symbol: "EURe", "USDC.e", or "xDAI" */
17
+ token: string;
18
+ /** Amount as a decimal string, e.g. "5.00" */
19
+ amount: string;
20
+ /** Recipient Ethereum address (0x...) */
21
+ to: string;
22
+ }
23
+ interface SignData {
24
+ /** The hash to sign (keccak256, 0x-prefixed) */
25
+ hash: string;
26
+ /** Breakdown of values that were hashed — useful for debugging */
27
+ components: {
28
+ safe: string;
29
+ token: string;
30
+ to: string;
31
+ amount: string;
32
+ payment_token: string;
33
+ payment: string;
34
+ nonce: number;
35
+ };
36
+ /** Human-readable signing instructions */
37
+ instructions: string;
38
+ }
39
+ interface PaymentIntent {
40
+ /** Unique payment ID */
41
+ paymentId: string;
42
+ /** Current status */
43
+ status: 'pending_signature';
44
+ /** ISO 8601 expiry timestamp */
45
+ expiresAt: string;
46
+ /** Data needed to sign the payment */
47
+ signData: SignData;
48
+ }
49
+ type PaymentStatus = 'pending_signature' | 'submitted' | 'confirmed' | 'expired' | 'failed';
50
+ interface PaymentResult {
51
+ /** Unique payment ID */
52
+ paymentId: string;
53
+ /** Final status */
54
+ status: PaymentStatus;
55
+ /** Token that was sent */
56
+ token: string;
57
+ /** Amount that was sent (human-readable) */
58
+ amount: string;
59
+ /** Recipient address */
60
+ to: string;
61
+ /** On-chain transaction hash (present when confirmed) */
62
+ txHash: string | null;
63
+ /** Error message (present when failed) */
64
+ errorMessage: string | null;
65
+ /** Block explorer URL for the transaction (chain-dependent) */
66
+ explorerUrl: string | null;
67
+ /** ISO 8601 timestamps */
68
+ createdAt: string;
69
+ signedAt: string | null;
70
+ submittedAt: string | null;
71
+ confirmedAt: string | null;
72
+ expiresAt: string;
73
+ }
74
+ /** Payment requirements from an HTTP 402 response (x402 protocol). */
75
+ interface X402PaymentRequired {
76
+ x402Version: number;
77
+ resource: {
78
+ url: string;
79
+ description?: string;
80
+ mimeType?: string;
81
+ };
82
+ accepts: X402PaymentOption[];
83
+ error?: string;
84
+ }
85
+ /** A single payment option from x402 PaymentRequired. */
86
+ interface X402PaymentOption {
87
+ scheme: string;
88
+ network: string;
89
+ amount: string;
90
+ asset: string;
91
+ payTo: string;
92
+ maxTimeoutSeconds: number;
93
+ extra?: Record<string, unknown>;
94
+ }
95
+ /** Receipt returned after a successful x402 payment. */
96
+ interface X402Receipt {
97
+ success: boolean;
98
+ paymentId: string;
99
+ txHash: string;
100
+ token: string;
101
+ amount: string;
102
+ to: string;
103
+ resourceUrl: string;
104
+ explorerUrl: string;
105
+ }
106
+ declare class HavenError extends Error {
107
+ readonly code: string;
108
+ readonly statusCode?: number | undefined;
109
+ readonly paymentId?: string | undefined;
110
+ constructor(message: string, code: string, statusCode?: number | undefined, paymentId?: string | undefined);
111
+ }
112
+ declare class HavenApiError extends HavenError {
113
+ readonly body?: unknown | undefined;
114
+ constructor(message: string, statusCode: number, body?: unknown | undefined);
115
+ }
116
+ declare class HavenSigningError extends HavenError {
117
+ constructor(message: string);
118
+ }
119
+ declare class HavenTimeoutError extends HavenError {
120
+ constructor(paymentId: string);
121
+ }
122
+
123
+ declare class HavenClient {
124
+ private readonly apiKey;
125
+ private readonly delegateKey;
126
+ private readonly baseUrl;
127
+ private readonly requestTimeout;
128
+ private readonly confirmationTimeout;
129
+ private readonly pollingInterval;
130
+ /** Delegate address derived from the private key (if provided) */
131
+ readonly delegateAddress: string | undefined;
132
+ constructor(config: HavenClientConfig);
133
+ /**
134
+ * Send a payment in one call.
135
+ *
136
+ * Creates the intent, signs the hash, submits the signature,
137
+ * and polls until confirmed (or throws on failure/timeout).
138
+ *
139
+ * Requires `delegateKey` to be set in the client config.
140
+ */
141
+ pay(request: PaymentRequest): Promise<PaymentResult>;
142
+ /**
143
+ * Step 1: Create a payment intent.
144
+ *
145
+ * Returns the intent with the hash to sign.
146
+ */
147
+ createIntent(request: PaymentRequest): Promise<PaymentIntent>;
148
+ /**
149
+ * Step 2: Sign a hash with the delegate key.
150
+ *
151
+ * Returns the 65-byte signature (0x-prefixed).
152
+ * Requires `delegateKey` to be set in the client config.
153
+ */
154
+ sign(hash: string): string;
155
+ /**
156
+ * Step 3: Submit a signature to execute the payment.
157
+ *
158
+ * The signature can come from `client.sign()` or from external signing.
159
+ */
160
+ submitSignature(paymentId: string, signature: string): Promise<{
161
+ status: string;
162
+ txHash?: string;
163
+ }>;
164
+ /**
165
+ * Get the current status of a payment.
166
+ */
167
+ getPayment(paymentId: string): Promise<PaymentResult>;
168
+ /**
169
+ * Poll until a payment reaches a terminal status (confirmed, failed, expired).
170
+ */
171
+ waitForConfirmation(paymentId: string): Promise<PaymentResult>;
172
+ /**
173
+ * Authorize an x402 payment.
174
+ *
175
+ * Takes the parsed PaymentRequired from a 402 response, selects a
176
+ * compatible payment option, signs and executes the payment through Haven.
177
+ *
178
+ * Requires `delegateKey` to be set in the client config.
179
+ */
180
+ authorizeX402(paymentRequired: X402PaymentRequired): Promise<X402Receipt>;
181
+ /**
182
+ * Fetch wrapper that automatically handles HTTP 402 responses.
183
+ *
184
+ * Works like the standard `fetch()` but intercepts 402 responses,
185
+ * pays via x402 through Haven, and retries the request.
186
+ *
187
+ * ```ts
188
+ * const response = await haven.fetch('https://paid-api.com/data')
189
+ * const data = await response.json()
190
+ * ```
191
+ *
192
+ * Requires `delegateKey` to be set in the client config.
193
+ */
194
+ fetch(url: string, init?: RequestInit): Promise<Response>;
195
+ /**
196
+ * Execute a tool call by name and input.
197
+ *
198
+ * Designed to plug directly into agent tool-call handlers:
199
+ *
200
+ * ```ts
201
+ * if (block.type === 'tool_use') {
202
+ * const result = await haven.executeTool(block.name, block.input)
203
+ * // send result back to the model
204
+ * }
205
+ * ```
206
+ */
207
+ executeTool(toolName: string, input: Record<string, unknown>): Promise<Record<string, unknown>>;
208
+ private post;
209
+ private get;
210
+ private request;
211
+ private mapPaymentResult;
212
+ }
213
+
214
+ /**
215
+ * Pre-built tool definitions for AI agent frameworks.
216
+ *
217
+ * These definitions describe the `make_payment` and `get_payment_status` tools
218
+ * in the formats expected by Claude (Anthropic) and OpenAI.
219
+ *
220
+ * Usage with Claude:
221
+ * const response = await anthropic.messages.create({
222
+ * tools: havenTools.claude(),
223
+ * ...
224
+ * })
225
+ *
226
+ * Usage with OpenAI:
227
+ * const response = await openai.chat.completions.create({
228
+ * tools: havenTools.openai(),
229
+ * ...
230
+ * })
231
+ */
232
+ interface ClaudeTool {
233
+ name: string;
234
+ description: string;
235
+ input_schema: {
236
+ type: 'object';
237
+ properties: Record<string, unknown>;
238
+ required: readonly string[];
239
+ };
240
+ }
241
+ declare function claudeTools(): ClaudeTool[];
242
+ interface OpenAITool {
243
+ type: 'function';
244
+ function: {
245
+ name: string;
246
+ description: string;
247
+ parameters: {
248
+ type: 'object';
249
+ properties: Record<string, unknown>;
250
+ required: readonly string[];
251
+ };
252
+ };
253
+ }
254
+ declare function openaiTools(): OpenAITool[];
255
+ declare const havenTools: {
256
+ /** Tool definitions in Anthropic/Claude format */
257
+ claude: typeof claudeTools;
258
+ /** Tool definitions in OpenAI function-calling format */
259
+ openai: typeof openaiTools;
260
+ };
261
+
262
+ /**
263
+ * Sign a hash using raw ECDSA (no Ethereum message prefix).
264
+ *
265
+ * This matches what Safe's AllowanceModule `checkSignature` expects —
266
+ * a direct ecrecover over the hash, NOT the "\x19Ethereum Signed Message" variant.
267
+ *
268
+ * Uses ethers.SigningKey.sign() instead of wallet.signMessage() to avoid the prefix.
269
+ */
270
+ declare function signHash(privateKey: string, hash: string): string;
271
+ /**
272
+ * Derive the Ethereum address from a private key.
273
+ */
274
+ declare function addressFromKey(privateKey: string): string;
275
+ /**
276
+ * Verify that a signature over a hash recovers to the expected address.
277
+ */
278
+ declare function verifySignature(hash: string, signature: string, expectedAddress: string): boolean;
279
+
280
+ /**
281
+ * x402 protocol support for the Haven SDK.
282
+ *
283
+ * Provides:
284
+ * - parsePaymentRequired() — extract payment requirements from a 402 response
285
+ * - encodePaymentProof() — encode a receipt as a PAYMENT-SIGNATURE header
286
+ *
287
+ * The main authorizeX402() and fetchWithPayment() are methods on HavenClient
288
+ * (see client.ts) since they need API access and signing.
289
+ */
290
+
291
+ /**
292
+ * Parse an HTTP 402 response into x402 PaymentRequired data.
293
+ *
294
+ * Supports:
295
+ * - v2: PAYMENT-REQUIRED header (base64 JSON)
296
+ * - v1 fallback: X-PAYMENT header or response body
297
+ */
298
+ declare function parsePaymentRequired(response: Response): X402PaymentRequired;
299
+ /**
300
+ * Select the best payment option from the x402 accepts array.
301
+ *
302
+ * Preference order:
303
+ * 1. Option on a Haven-supported network with a known token
304
+ * 2. Any option on a Haven-supported network
305
+ * 3. null — no compatible option
306
+ */
307
+ declare function selectPaymentOption(accepts: X402PaymentOption[]): X402PaymentOption | null;
308
+ /**
309
+ * Encode a payment receipt as a base64 PAYMENT-SIGNATURE header value.
310
+ *
311
+ * This follows the x402 v2 protocol — the server's facilitator will
312
+ * verify the on-chain transaction referenced by tx_hash.
313
+ */
314
+ declare function encodePaymentProof(receipt: {
315
+ txHash: string;
316
+ paymentId: string;
317
+ token: string;
318
+ amount: string;
319
+ to: string;
320
+ }): string;
321
+
322
+ export { type ClaudeTool, HavenApiError, HavenClient, type HavenClientConfig, HavenError, HavenSigningError, HavenTimeoutError, type OpenAITool, type PaymentIntent, type PaymentRequest, type PaymentResult, type PaymentStatus, type SignData, type X402PaymentOption, type X402PaymentRequired, type X402Receipt, addressFromKey, encodePaymentProof, havenTools, parsePaymentRequired, selectPaymentOption, signHash, verifySignature };