@haven_ai/sdk 0.1.5 → 0.1.7
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 +6 -13
- package/dist/index.cjs +64 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1081 -0
- package/dist/index.d.ts +1081 -0
- package/dist/index.js +64 -18
- package/dist/index.js.map +1 -1
- package/examples/x402_openapi_python.py +2 -2
- package/package.json +1 -1
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1081 @@
|
|
|
1
|
+
import { PaymentRequirements } from 'x402/types';
|
|
2
|
+
|
|
3
|
+
interface HavenClientConfig {
|
|
4
|
+
/** Haven API key (sk_agent_xxx) */
|
|
5
|
+
apiKey: string;
|
|
6
|
+
/** Agent's delegate EOA private key. If provided, the SDK handles signing automatically. */
|
|
7
|
+
delegateKey?: string;
|
|
8
|
+
/** Haven API base URL (default: http://localhost:3001) */
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
/** Optional wallet identity to send as the x402-wallet header. */
|
|
11
|
+
x402Wallet?: string;
|
|
12
|
+
/** Timeout in ms for individual HTTP requests (default: 30000) */
|
|
13
|
+
requestTimeout?: number;
|
|
14
|
+
/** Timeout in ms when polling for tx confirmation (default: 90000) */
|
|
15
|
+
confirmationTimeout?: number;
|
|
16
|
+
/** Polling interval in ms when waiting for confirmation (default: 3000) */
|
|
17
|
+
pollingInterval?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Extra headers to attach to every request to the Haven API.
|
|
20
|
+
*
|
|
21
|
+
* Used by the MCP server to tag requests with `X-Haven-MCP-Tool: <name>`
|
|
22
|
+
* so the backend can record an audit-log entry per tool invocation. Has
|
|
23
|
+
* no effect on outbound merchant requests (x402 / MPP) — those are
|
|
24
|
+
* standard HTTP and never carry Haven-internal headers.
|
|
25
|
+
*/
|
|
26
|
+
defaultHeaders?: Record<string, string>;
|
|
27
|
+
}
|
|
28
|
+
interface PaymentRequest {
|
|
29
|
+
/** Token symbol: "EURe", "USDC.e", or "xDAI" */
|
|
30
|
+
token: string;
|
|
31
|
+
/** Amount as a decimal string, e.g. "5.00" */
|
|
32
|
+
amount: string;
|
|
33
|
+
/** Recipient Ethereum address (0x...) */
|
|
34
|
+
to: string;
|
|
35
|
+
}
|
|
36
|
+
interface SignData {
|
|
37
|
+
/** The hash to sign (keccak256, 0x-prefixed) */
|
|
38
|
+
hash: string;
|
|
39
|
+
/** Breakdown of values that were hashed — useful for debugging */
|
|
40
|
+
components: {
|
|
41
|
+
safe: string;
|
|
42
|
+
token: string;
|
|
43
|
+
to: string;
|
|
44
|
+
amount: string;
|
|
45
|
+
payment_token: string;
|
|
46
|
+
payment: string;
|
|
47
|
+
nonce: number;
|
|
48
|
+
};
|
|
49
|
+
/** Human-readable signing instructions */
|
|
50
|
+
instructions: string;
|
|
51
|
+
}
|
|
52
|
+
interface PaymentIntent {
|
|
53
|
+
/** Unique payment ID */
|
|
54
|
+
paymentId: string;
|
|
55
|
+
/** Current status */
|
|
56
|
+
status: 'pending_signature';
|
|
57
|
+
/** ISO 8601 expiry timestamp */
|
|
58
|
+
expiresAt: string;
|
|
59
|
+
/** Data needed to sign the payment */
|
|
60
|
+
signData: SignData;
|
|
61
|
+
}
|
|
62
|
+
type PaymentStatus = 'pending_signature' | 'submitted' | 'confirmed' | 'pending_approval' | 'approved' | 'proposed' | 'executed' | 'rejected' | 'expired' | 'failed';
|
|
63
|
+
interface PaymentResult {
|
|
64
|
+
/** Unique payment ID */
|
|
65
|
+
paymentId: string;
|
|
66
|
+
/** Final status */
|
|
67
|
+
status: PaymentStatus;
|
|
68
|
+
/** Token that was sent */
|
|
69
|
+
token: string;
|
|
70
|
+
/** Amount that was sent (human-readable) */
|
|
71
|
+
amount: string;
|
|
72
|
+
/** Recipient address */
|
|
73
|
+
to: string;
|
|
74
|
+
/** On-chain transaction hash (present when confirmed) */
|
|
75
|
+
txHash: string | null;
|
|
76
|
+
/** Error message (present when failed) */
|
|
77
|
+
errorMessage: string | null;
|
|
78
|
+
/** Block explorer URL for the transaction (chain-dependent) */
|
|
79
|
+
explorerUrl: string | null;
|
|
80
|
+
/** ISO 8601 timestamps */
|
|
81
|
+
createdAt: string;
|
|
82
|
+
signedAt: string | null;
|
|
83
|
+
submittedAt: string | null;
|
|
84
|
+
confirmedAt: string | null;
|
|
85
|
+
expiresAt: string;
|
|
86
|
+
}
|
|
87
|
+
/** Payment requirements from an HTTP 402 response (x402 protocol). */
|
|
88
|
+
interface X402PaymentRequired {
|
|
89
|
+
x402Version: number;
|
|
90
|
+
resource: {
|
|
91
|
+
url: string;
|
|
92
|
+
description?: string;
|
|
93
|
+
mimeType?: string;
|
|
94
|
+
};
|
|
95
|
+
accepts: X402PaymentOption[];
|
|
96
|
+
error?: string;
|
|
97
|
+
}
|
|
98
|
+
/** A single payment option from x402 PaymentRequired. */
|
|
99
|
+
interface X402PaymentOption {
|
|
100
|
+
scheme: string;
|
|
101
|
+
network: string;
|
|
102
|
+
amount: string;
|
|
103
|
+
maxAmountRequired?: string;
|
|
104
|
+
resource?: string;
|
|
105
|
+
description?: string;
|
|
106
|
+
mimeType?: string;
|
|
107
|
+
asset: string;
|
|
108
|
+
payTo: string;
|
|
109
|
+
maxTimeoutSeconds: number;
|
|
110
|
+
extra?: Record<string, unknown>;
|
|
111
|
+
}
|
|
112
|
+
/** Receipt returned after a successful x402 payment. */
|
|
113
|
+
interface X402Receipt {
|
|
114
|
+
success: boolean;
|
|
115
|
+
paymentId: string;
|
|
116
|
+
txHash: string;
|
|
117
|
+
token: string;
|
|
118
|
+
amount: string;
|
|
119
|
+
to: string;
|
|
120
|
+
resourceUrl: string;
|
|
121
|
+
explorerUrl: string;
|
|
122
|
+
accepted?: X402PaymentOption;
|
|
123
|
+
paymentHeader?: string;
|
|
124
|
+
merchantTo?: string | null;
|
|
125
|
+
payer?: string;
|
|
126
|
+
chainId?: number;
|
|
127
|
+
haven?: {
|
|
128
|
+
paymentId: string;
|
|
129
|
+
fundingTxHash: string;
|
|
130
|
+
fundingExplorerUrl: string;
|
|
131
|
+
};
|
|
132
|
+
merchant?: {
|
|
133
|
+
payTo: string | null;
|
|
134
|
+
settlementTxHash?: string | null;
|
|
135
|
+
settlementExplorerUrl?: string | null;
|
|
136
|
+
};
|
|
137
|
+
x402?: {
|
|
138
|
+
amount: string;
|
|
139
|
+
token: string;
|
|
140
|
+
network: string;
|
|
141
|
+
asset: string;
|
|
142
|
+
resource: string;
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
interface X402AuthorizationOptions {
|
|
146
|
+
/** Stable caller-supplied key for this user intent. Prevents duplicate approvals across fresh 402 quotes. */
|
|
147
|
+
idempotencyKey?: string;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Keyless x402 construct result.
|
|
151
|
+
*
|
|
152
|
+
* Returned by `createX402Intent` — the non-custodial half of an x402 payment.
|
|
153
|
+
* It carries the unsigned funding hash (`signData.hash`, Safe → delegate EOA)
|
|
154
|
+
* plus everything the *edge* needs to build and sign the EIP-3009 merchant
|
|
155
|
+
* header itself. The construct path never signs; both delegate signatures
|
|
156
|
+
* (funding hash + merchant header) happen on the machine that holds the key.
|
|
157
|
+
*/
|
|
158
|
+
interface X402Intent {
|
|
159
|
+
/** Haven payment id for the funding transfer. */
|
|
160
|
+
paymentId: string;
|
|
161
|
+
status: 'pending_signature';
|
|
162
|
+
/** ISO 8601 expiry of the funding intent, if returned. */
|
|
163
|
+
expiresAt?: string;
|
|
164
|
+
/** The unsigned funding hash to sign with the delegate key (Safe → delegate EOA). */
|
|
165
|
+
signData: SignData;
|
|
166
|
+
/** The selected x402 option — the edge needs this to build the EIP-3009 header. */
|
|
167
|
+
accepted: X402PaymentOption;
|
|
168
|
+
/** Resource URL the 402 came from. */
|
|
169
|
+
resourceUrl: string;
|
|
170
|
+
/** Merchant payTo address (the final recipient of the EIP-3009 transfer). */
|
|
171
|
+
merchantTo: string;
|
|
172
|
+
/** Atomic amount the edge signer must authorize in the merchant header. */
|
|
173
|
+
amountAtomic: string;
|
|
174
|
+
/** Token contract the merchant header must pay. */
|
|
175
|
+
asset: string;
|
|
176
|
+
/** x402 network the merchant header must use. */
|
|
177
|
+
network: string;
|
|
178
|
+
/** Haven-authenticated binding over the x402 expected context. */
|
|
179
|
+
expectedAuth: X402ExpectedAuth;
|
|
180
|
+
/** Delegate EOA the funding transfer tops up (the x402 payer). */
|
|
181
|
+
fundingTo: string;
|
|
182
|
+
}
|
|
183
|
+
interface X402ExpectedContext {
|
|
184
|
+
paymentId: string;
|
|
185
|
+
payloadHash: string;
|
|
186
|
+
resourceUrl: string;
|
|
187
|
+
merchantTo: string;
|
|
188
|
+
amount: string;
|
|
189
|
+
asset: string;
|
|
190
|
+
network: string;
|
|
191
|
+
}
|
|
192
|
+
interface X402ExpectedAuth {
|
|
193
|
+
version: 1;
|
|
194
|
+
message: string;
|
|
195
|
+
signature: string;
|
|
196
|
+
signer: string;
|
|
197
|
+
}
|
|
198
|
+
/** Serializable HTTP request state for retrying the same x402 merchant request. */
|
|
199
|
+
interface X402RequestSnapshot {
|
|
200
|
+
url: string;
|
|
201
|
+
method: string;
|
|
202
|
+
headers: [string, string][];
|
|
203
|
+
body?: string;
|
|
204
|
+
}
|
|
205
|
+
/** Quote parsed from an HTTP 402 response without creating a Haven payment. */
|
|
206
|
+
interface X402Quote {
|
|
207
|
+
rail: 'x402';
|
|
208
|
+
idempotencyKey: string;
|
|
209
|
+
paymentRequired: X402PaymentRequired;
|
|
210
|
+
accepted: X402PaymentOption;
|
|
211
|
+
request: X402RequestSnapshot;
|
|
212
|
+
resourceUrl: string;
|
|
213
|
+
description: string | null;
|
|
214
|
+
mimeType: string | null;
|
|
215
|
+
amountAtomic: string;
|
|
216
|
+
amount: string;
|
|
217
|
+
token: string;
|
|
218
|
+
asset: string;
|
|
219
|
+
network: string;
|
|
220
|
+
chainId: number | null;
|
|
221
|
+
merchantAddress: string;
|
|
222
|
+
maxTimeoutSeconds: number;
|
|
223
|
+
}
|
|
224
|
+
/** State bundle an agent can persist while waiting for manual x402 approval. */
|
|
225
|
+
interface X402ResumeState {
|
|
226
|
+
rail: 'x402';
|
|
227
|
+
paymentId: string;
|
|
228
|
+
idempotencyKey: string;
|
|
229
|
+
paymentRequired: X402PaymentRequired;
|
|
230
|
+
accepted: X402PaymentOption;
|
|
231
|
+
url: string;
|
|
232
|
+
request?: X402RequestSnapshot;
|
|
233
|
+
resourceUrl: string;
|
|
234
|
+
description: string | null;
|
|
235
|
+
amountAtomic: string;
|
|
236
|
+
amount: string;
|
|
237
|
+
token: string;
|
|
238
|
+
asset: string;
|
|
239
|
+
network: string;
|
|
240
|
+
chainId: number | null;
|
|
241
|
+
merchantAddress: string;
|
|
242
|
+
}
|
|
243
|
+
interface MppAuthorizationOptions {
|
|
244
|
+
/** Stable caller-supplied key for this user intent. Prevents duplicate approvals across retries. */
|
|
245
|
+
idempotencyKey?: string;
|
|
246
|
+
}
|
|
247
|
+
/** Quote parsed from an MPP challenge without creating a Haven payment. */
|
|
248
|
+
interface MppQuote {
|
|
249
|
+
rail: 'mpp';
|
|
250
|
+
paymentRail: MachinePaymentRail;
|
|
251
|
+
idempotencyKey: string;
|
|
252
|
+
challenge: MachinePaymentChallenge;
|
|
253
|
+
request: X402RequestSnapshot;
|
|
254
|
+
resourceUrl: string;
|
|
255
|
+
description: string | null;
|
|
256
|
+
amountAtomic: string;
|
|
257
|
+
amount: string;
|
|
258
|
+
token: string;
|
|
259
|
+
asset: string;
|
|
260
|
+
network: string;
|
|
261
|
+
chainId: number;
|
|
262
|
+
merchantAddress: string;
|
|
263
|
+
expiresAt: string;
|
|
264
|
+
}
|
|
265
|
+
/** State bundle an agent can persist while waiting for manual MPP approval. */
|
|
266
|
+
interface MppResumeState {
|
|
267
|
+
rail: 'mpp';
|
|
268
|
+
paymentRail: MachinePaymentRail;
|
|
269
|
+
paymentId: string;
|
|
270
|
+
idempotencyKey: string;
|
|
271
|
+
challenge: MachinePaymentChallenge;
|
|
272
|
+
url: string;
|
|
273
|
+
request?: X402RequestSnapshot;
|
|
274
|
+
resourceUrl: string;
|
|
275
|
+
description: string | null;
|
|
276
|
+
amountAtomic: string;
|
|
277
|
+
amount: string;
|
|
278
|
+
token: string;
|
|
279
|
+
asset: string;
|
|
280
|
+
network: string;
|
|
281
|
+
chainId: number;
|
|
282
|
+
merchantAddress: string;
|
|
283
|
+
expiresAt: string;
|
|
284
|
+
}
|
|
285
|
+
type PaymentResumeState = X402ResumeState | MppResumeState;
|
|
286
|
+
interface ResumeAuthorizedX402Input extends X402AuthorizationOptions {
|
|
287
|
+
/** Payment or approval request ID returned by authorizeX402 / haven.fetch. */
|
|
288
|
+
paymentId: string;
|
|
289
|
+
/** Original or freshly parsed x402 requirements for the merchant retry. */
|
|
290
|
+
paymentRequired: X402PaymentRequired;
|
|
291
|
+
}
|
|
292
|
+
interface ResumeX402PaymentInput extends X402AuthorizationOptions {
|
|
293
|
+
/** Payment or approval request ID returned by authorizeX402 / haven.fetch. */
|
|
294
|
+
paymentId: string;
|
|
295
|
+
/** Original paid URL. If paymentRequired is omitted, Haven will call it once to re-read the 402 challenge. */
|
|
296
|
+
url: string;
|
|
297
|
+
/** Original fetch options. Reused for the 402 probe and final merchant retry. */
|
|
298
|
+
init?: RequestInit;
|
|
299
|
+
/** Serializable original request captured by quoteX402() / pending approval errors. */
|
|
300
|
+
request?: X402RequestSnapshot;
|
|
301
|
+
/** Original or freshly parsed x402 requirements. Supplying this avoids an extra merchant 402 probe. */
|
|
302
|
+
paymentRequired?: X402PaymentRequired;
|
|
303
|
+
}
|
|
304
|
+
interface ResumeAuthorizedMppInput extends MppAuthorizationOptions {
|
|
305
|
+
/** Payment or approval request ID returned by authorizeMachinePayment / haven.fetch. */
|
|
306
|
+
paymentId: string;
|
|
307
|
+
/** Original MPP challenge returned by the paid resource. */
|
|
308
|
+
challenge: MachinePaymentChallenge;
|
|
309
|
+
}
|
|
310
|
+
interface ResumeMppPaymentInput extends MppAuthorizationOptions {
|
|
311
|
+
/** Payment or approval request ID returned by authorizeMachinePayment / haven.fetch. */
|
|
312
|
+
paymentId: string;
|
|
313
|
+
/** Original paid URL. If challenge is omitted, Haven will call it once to re-read the MPP challenge. */
|
|
314
|
+
url: string;
|
|
315
|
+
/** Original fetch options. Reused for the 402 probe and final merchant retry. */
|
|
316
|
+
init?: RequestInit;
|
|
317
|
+
/** Serializable original request captured by quoteMpp() / pending approval errors. */
|
|
318
|
+
request?: X402RequestSnapshot;
|
|
319
|
+
/** Original MPP challenge. Supplying this avoids an extra paid-resource 402 probe. */
|
|
320
|
+
challenge?: MachinePaymentChallenge;
|
|
321
|
+
}
|
|
322
|
+
type MachinePaymentRail = 'x402' | 'mpp_demo' | 'mpp_crypto' | 'stripe_deposit' | 'spt';
|
|
323
|
+
interface MachinePaymentChallenge {
|
|
324
|
+
rail: MachinePaymentRail;
|
|
325
|
+
version: string;
|
|
326
|
+
challengeId: string;
|
|
327
|
+
resource: string;
|
|
328
|
+
description: string;
|
|
329
|
+
network: {
|
|
330
|
+
chainId: number;
|
|
331
|
+
name: 'base';
|
|
332
|
+
};
|
|
333
|
+
asset: {
|
|
334
|
+
symbol: 'USDC';
|
|
335
|
+
address: string;
|
|
336
|
+
decimals: 6;
|
|
337
|
+
};
|
|
338
|
+
amount: {
|
|
339
|
+
display: string;
|
|
340
|
+
atomic: string;
|
|
341
|
+
};
|
|
342
|
+
recipient: string;
|
|
343
|
+
expiresAt: string;
|
|
344
|
+
metadata?: Record<string, unknown>;
|
|
345
|
+
}
|
|
346
|
+
interface MachinePaymentReceipt {
|
|
347
|
+
success: boolean;
|
|
348
|
+
rail: MachinePaymentRail;
|
|
349
|
+
paymentId: string;
|
|
350
|
+
challengeId: string;
|
|
351
|
+
txHash: string;
|
|
352
|
+
token: string;
|
|
353
|
+
amount: string;
|
|
354
|
+
to: string;
|
|
355
|
+
resourceUrl: string;
|
|
356
|
+
explorerUrl: string;
|
|
357
|
+
payer?: string;
|
|
358
|
+
chainId?: number;
|
|
359
|
+
proofHeader: string;
|
|
360
|
+
}
|
|
361
|
+
interface HavenAgent {
|
|
362
|
+
id: string;
|
|
363
|
+
name: string;
|
|
364
|
+
status: string;
|
|
365
|
+
safeAddress: string;
|
|
366
|
+
delegateAddress: string;
|
|
367
|
+
chainId: number;
|
|
368
|
+
}
|
|
369
|
+
interface HavenAllowance {
|
|
370
|
+
id: string;
|
|
371
|
+
tokenAddress: string;
|
|
372
|
+
tokenSymbol: string;
|
|
373
|
+
configuredAmount: string;
|
|
374
|
+
resetPeriodMin: number;
|
|
375
|
+
onchain: {
|
|
376
|
+
amount: string;
|
|
377
|
+
spent: string;
|
|
378
|
+
remaining: string;
|
|
379
|
+
effectiveSpent: string;
|
|
380
|
+
resetTimeMin: number;
|
|
381
|
+
lastResetMin: number;
|
|
382
|
+
nonce: number;
|
|
383
|
+
isResetPending: boolean;
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
interface HavenAllowanceSummary {
|
|
387
|
+
agentId: string;
|
|
388
|
+
safeAddress: string;
|
|
389
|
+
delegateAddress: string;
|
|
390
|
+
chainId: number;
|
|
391
|
+
allowances: HavenAllowance[];
|
|
392
|
+
}
|
|
393
|
+
interface HavenPaymentReceipt {
|
|
394
|
+
id: string;
|
|
395
|
+
paymentId: string;
|
|
396
|
+
paymentIntentId?: string | null;
|
|
397
|
+
approvalRequestId?: string | null;
|
|
398
|
+
rail: string;
|
|
399
|
+
proofStatus: string;
|
|
400
|
+
txHash: string;
|
|
401
|
+
chainId: number;
|
|
402
|
+
resourceUrl: string;
|
|
403
|
+
merchantAddress: string | null;
|
|
404
|
+
payerAddress: string;
|
|
405
|
+
settlementAddress: string;
|
|
406
|
+
tokenSymbol: string;
|
|
407
|
+
tokenAddress: string;
|
|
408
|
+
amountRaw: string;
|
|
409
|
+
amount: string;
|
|
410
|
+
challengeId: string | null;
|
|
411
|
+
idempotencyKey: string | null;
|
|
412
|
+
challengePayload?: Record<string, unknown> | null;
|
|
413
|
+
selectedPayment?: Record<string, unknown> | null;
|
|
414
|
+
paymentProofHeaderName: string | null;
|
|
415
|
+
protocolReceiptHeaderName: string | null;
|
|
416
|
+
protocolReceiptPayload?: Record<string, unknown> | null;
|
|
417
|
+
merchantStatus: number | null;
|
|
418
|
+
confirmedAt: string | null;
|
|
419
|
+
createdAt: string;
|
|
420
|
+
updatedAt: string;
|
|
421
|
+
}
|
|
422
|
+
type PaymentStateKind = 'payment_intent' | 'approval_request';
|
|
423
|
+
interface AgentPaymentEnumSchema {
|
|
424
|
+
type: 'string';
|
|
425
|
+
enum: readonly string[];
|
|
426
|
+
description: string;
|
|
427
|
+
'x-enumDescriptions': Record<string, string>;
|
|
428
|
+
}
|
|
429
|
+
declare const AgentPaymentPhase: {
|
|
430
|
+
/** The agent must sign and submit the prepared payment before Haven can relay it. */
|
|
431
|
+
readonly AgentSignatureRequired: "agent_signature_required";
|
|
432
|
+
/** Haven has received the signed payment and the agent should poll for confirmation. */
|
|
433
|
+
readonly PaymentSubmitted: "payment_submitted";
|
|
434
|
+
/** The direct payment is confirmed; the agent does not need to do more for this payment id. */
|
|
435
|
+
readonly PaymentConfirmed: "payment_confirmed";
|
|
436
|
+
/** The payment needs wallet owner approval in Haven before it can continue. */
|
|
437
|
+
readonly UserApprovalRequired: "user_approval_required";
|
|
438
|
+
/** The wallet owner approved the request and still needs to complete the funding payment. */
|
|
439
|
+
readonly UserExecutionRequired: "user_execution_required";
|
|
440
|
+
/** The funding payment was proposed and is waiting for the remaining account approvals. */
|
|
441
|
+
readonly WaitingForAdditionalApprovals: "waiting_for_additional_approvals";
|
|
442
|
+
/** The Haven funding leg was sent; the agent can continue the merchant/protocol leg. */
|
|
443
|
+
readonly FundingSent: "funding_sent";
|
|
444
|
+
/** The wallet owner rejected the request; the agent should stop and tell the user. */
|
|
445
|
+
readonly Rejected: "rejected";
|
|
446
|
+
/** The payment or approval request expired before completion. */
|
|
447
|
+
readonly Expired: "expired";
|
|
448
|
+
/** Haven could not complete the payment; the agent should stop and surface the failure. */
|
|
449
|
+
readonly Failed: "failed";
|
|
450
|
+
/**
|
|
451
|
+
* Pre-flight check determined the delegate's existing balance plus the
|
|
452
|
+
* remaining on-chain allowance cannot cover the requested amount, so no
|
|
453
|
+
* payment intent was created. Distinct from `UserApprovalRequired`: there
|
|
454
|
+
* is no approval that would fix this — the originating Safe needs more
|
|
455
|
+
* funds or the agent's per-token allowance needs to be raised first.
|
|
456
|
+
*/
|
|
457
|
+
readonly InsufficientFunds: "insufficient_funds";
|
|
458
|
+
};
|
|
459
|
+
type AgentPaymentPhase = (typeof AgentPaymentPhase)[keyof typeof AgentPaymentPhase];
|
|
460
|
+
declare const AgentPaymentNextAction: {
|
|
461
|
+
/** Sign with the delegate key and submit the payment to Haven. */
|
|
462
|
+
readonly SignAndSubmitPayment: "sign_and_submit_payment";
|
|
463
|
+
/** Poll getPaymentStatus later using this payment id. */
|
|
464
|
+
readonly CheckStatusLater: "check_status_later";
|
|
465
|
+
/** No further agent action is required for this payment id. */
|
|
466
|
+
readonly None: "none";
|
|
467
|
+
/** Wait for the wallet owner to approve or reject the request in Haven. */
|
|
468
|
+
readonly WaitForUserApproval: "wait_for_user_approval";
|
|
469
|
+
/** Wait for the wallet owner to finish sending the approved funding payment. */
|
|
470
|
+
readonly WaitForUserToCompletePayment: "wait_for_user_to_complete_payment";
|
|
471
|
+
/** Resume this payment id and retry the original x402 request with the merchant payment header. */
|
|
472
|
+
readonly RetryOriginalX402Request: "retry_original_x402_request";
|
|
473
|
+
/** Stop retrying this payment and tell the user what happened. */
|
|
474
|
+
readonly StopAndTellUser: "stop_and_tell_user";
|
|
475
|
+
/** Ask again only if the user still wants the payment after expiry. */
|
|
476
|
+
readonly RequestAgainIfUserStillWantsIt: "request_again_if_user_still_wants_it";
|
|
477
|
+
/**
|
|
478
|
+
* Stop and tell the user that the originating Safe needs to be funded or
|
|
479
|
+
* the agent's per-token allowance needs to be raised before the payment
|
|
480
|
+
* can succeed. A user approval will not fix this state on its own.
|
|
481
|
+
*/
|
|
482
|
+
readonly FundSafeOrRaiseAllowance: "fund_safe_or_raise_allowance";
|
|
483
|
+
};
|
|
484
|
+
type AgentPaymentNextAction = (typeof AgentPaymentNextAction)[keyof typeof AgentPaymentNextAction];
|
|
485
|
+
/**
|
|
486
|
+
* Stable rail identifier carried on Haven agent payment responses and resume
|
|
487
|
+
* state.
|
|
488
|
+
*
|
|
489
|
+
* Two layers of vocabulary share this enum because both reach the wire:
|
|
490
|
+
*
|
|
491
|
+
* - **Categorical rails** identify the rail family and are used as
|
|
492
|
+
* discriminators on `PaymentResumeState`: `direct`, `x402`, `mpp`.
|
|
493
|
+
* - **Granular rails** identify the specific protocol the backend persists
|
|
494
|
+
* and returns on response bodies: `mpp_demo`, `mpp_crypto`,
|
|
495
|
+
* `stripe_deposit`, `spt`. `x402` doubles as both categorical and
|
|
496
|
+
* granular.
|
|
497
|
+
*
|
|
498
|
+
* Consumers reading the top-level `rail` field on a payment status response
|
|
499
|
+
* should treat any `mpp*` value as the MPP family; consumers reading the
|
|
500
|
+
* `rail` field on a `MppResumeState` will always see the categorical `mpp`,
|
|
501
|
+
* with the granular value on `paymentRail`.
|
|
502
|
+
*/
|
|
503
|
+
declare const AgentPaymentRail: {
|
|
504
|
+
/** Standard Haven payment from the user's Safe through an approved delegate allowance. */
|
|
505
|
+
readonly Direct: "direct";
|
|
506
|
+
/** x402 HTTP 402 payment flow with a Haven funding leg and merchant retry leg. */
|
|
507
|
+
readonly X402: "x402";
|
|
508
|
+
/** Machine Payment Protocol family — categorical value used as a resume-state discriminator. */
|
|
509
|
+
readonly Mpp: "mpp";
|
|
510
|
+
/** Haven internal MPP demo rail. Not for production traffic. */
|
|
511
|
+
readonly MppDemo: "mpp_demo";
|
|
512
|
+
/** Crypto-settled MPP rail. */
|
|
513
|
+
readonly MppCrypto: "mpp_crypto";
|
|
514
|
+
/** Stripe-deposit-backed MPP rail. */
|
|
515
|
+
readonly StripeDeposit: "stripe_deposit";
|
|
516
|
+
/** Stripe Payment Token MPP rail. */
|
|
517
|
+
readonly Spt: "spt";
|
|
518
|
+
};
|
|
519
|
+
type AgentPaymentRail = (typeof AgentPaymentRail)[keyof typeof AgentPaymentRail];
|
|
520
|
+
type PaymentPhase = AgentPaymentPhase;
|
|
521
|
+
type PaymentNextAction = AgentPaymentNextAction;
|
|
522
|
+
declare const AGENT_PAYMENT_PHASE_VALUES: ("rejected" | "expired" | "failed" | "agent_signature_required" | "payment_submitted" | "payment_confirmed" | "user_approval_required" | "user_execution_required" | "waiting_for_additional_approvals" | "funding_sent" | "insufficient_funds")[];
|
|
523
|
+
declare const AGENT_PAYMENT_NEXT_ACTION_VALUES: ("sign_and_submit_payment" | "check_status_later" | "none" | "wait_for_user_approval" | "wait_for_user_to_complete_payment" | "retry_original_x402_request" | "stop_and_tell_user" | "request_again_if_user_still_wants_it" | "fund_safe_or_raise_allowance")[];
|
|
524
|
+
declare const AGENT_PAYMENT_RAIL_VALUES: ("x402" | "mpp" | "mpp_demo" | "mpp_crypto" | "stripe_deposit" | "spt" | "direct")[];
|
|
525
|
+
declare const AgentPaymentPhaseDescriptions: Record<AgentPaymentPhase, string>;
|
|
526
|
+
declare const AgentPaymentNextActionDescriptions: Record<AgentPaymentNextAction, string>;
|
|
527
|
+
declare const AgentPaymentRailDescriptions: Record<AgentPaymentRail, string>;
|
|
528
|
+
declare const AgentPaymentPhaseSchema: AgentPaymentEnumSchema;
|
|
529
|
+
declare const AgentPaymentNextActionSchema: AgentPaymentEnumSchema;
|
|
530
|
+
declare const AgentPaymentRailSchema: AgentPaymentEnumSchema;
|
|
531
|
+
interface PaymentStatusResult {
|
|
532
|
+
paymentId: string;
|
|
533
|
+
kind: PaymentStateKind;
|
|
534
|
+
rail: string;
|
|
535
|
+
status: PaymentStatus | string;
|
|
536
|
+
phase: PaymentPhase;
|
|
537
|
+
nextAction: PaymentNextAction;
|
|
538
|
+
amount: string;
|
|
539
|
+
token: string;
|
|
540
|
+
resourceUrl: string | null;
|
|
541
|
+
merchantAddress: string | null;
|
|
542
|
+
txHash: string | null;
|
|
543
|
+
expiresAt: string;
|
|
544
|
+
chainId: number;
|
|
545
|
+
message: string;
|
|
546
|
+
amountAtomic?: string | null;
|
|
547
|
+
asset?: string | null;
|
|
548
|
+
network?: string | null;
|
|
549
|
+
description?: string | null;
|
|
550
|
+
idempotencyKey?: string | null;
|
|
551
|
+
x402?: {
|
|
552
|
+
amountAtomic: string | null;
|
|
553
|
+
asset: string | null;
|
|
554
|
+
network: string | null;
|
|
555
|
+
resourceUrl: string | null;
|
|
556
|
+
merchantAddress: string | null;
|
|
557
|
+
description: string | null;
|
|
558
|
+
idempotencyKey: string | null;
|
|
559
|
+
};
|
|
560
|
+
mpp?: {
|
|
561
|
+
amountAtomic: string | null;
|
|
562
|
+
asset: string | null;
|
|
563
|
+
network: string | null;
|
|
564
|
+
resourceUrl: string | null;
|
|
565
|
+
merchantAddress: string | null;
|
|
566
|
+
description: string | null;
|
|
567
|
+
idempotencyKey: string | null;
|
|
568
|
+
challengeId: string | null;
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
interface PendingApproval extends PaymentStatusResult {
|
|
572
|
+
kind: 'approval_request';
|
|
573
|
+
status: 'pending_approval' | 'pending' | string;
|
|
574
|
+
phase: typeof AgentPaymentPhase.UserApprovalRequired;
|
|
575
|
+
nextAction: typeof AgentPaymentNextAction.WaitForUserApproval;
|
|
576
|
+
requested?: string;
|
|
577
|
+
remaining?: string | null;
|
|
578
|
+
}
|
|
579
|
+
declare class HavenError extends Error {
|
|
580
|
+
readonly code: string;
|
|
581
|
+
readonly statusCode?: number | undefined;
|
|
582
|
+
readonly paymentId?: string | undefined;
|
|
583
|
+
constructor(message: string, code: string, statusCode?: number | undefined, paymentId?: string | undefined);
|
|
584
|
+
}
|
|
585
|
+
declare class HavenApiError extends HavenError {
|
|
586
|
+
readonly body?: unknown | undefined;
|
|
587
|
+
constructor(message: string, statusCode: number, body?: unknown | undefined, paymentId?: string);
|
|
588
|
+
}
|
|
589
|
+
declare class HavenPaymentStateError extends HavenApiError {
|
|
590
|
+
readonly state: PaymentStatusResult;
|
|
591
|
+
resumeState?: X402ResumeState | MppResumeState;
|
|
592
|
+
constructor(message: string, statusCode: number, state: PaymentStatusResult, body?: unknown);
|
|
593
|
+
get status(): string;
|
|
594
|
+
get phase(): PaymentPhase;
|
|
595
|
+
get nextAction(): PaymentNextAction;
|
|
596
|
+
}
|
|
597
|
+
declare class HavenSigningError extends HavenError {
|
|
598
|
+
constructor(message: string);
|
|
599
|
+
}
|
|
600
|
+
declare class HavenTimeoutError extends HavenError {
|
|
601
|
+
constructor(paymentId: string);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
declare class HavenClient {
|
|
605
|
+
private readonly apiKey;
|
|
606
|
+
private readonly delegateKey;
|
|
607
|
+
private readonly baseUrl;
|
|
608
|
+
private readonly x402Wallet;
|
|
609
|
+
private readonly requestTimeout;
|
|
610
|
+
private readonly confirmationTimeout;
|
|
611
|
+
private readonly pollingInterval;
|
|
612
|
+
private readonly inFlightX402;
|
|
613
|
+
private readonly x402ReceiptCache;
|
|
614
|
+
private readonly inFlightMachinePayments;
|
|
615
|
+
/**
|
|
616
|
+
* Setup-time headers configured via `HavenClientConfig.defaultHeaders`.
|
|
617
|
+
* Read-only after construction — use `withRequestContext` for per-call
|
|
618
|
+
* scoping so concurrent requests don't race on shared mutable state.
|
|
619
|
+
*/
|
|
620
|
+
private readonly defaultHeaders;
|
|
621
|
+
/**
|
|
622
|
+
* Async-local store for per-request context (currently: extra headers).
|
|
623
|
+
* Each `withRequestContext` invocation produces an isolated store, so
|
|
624
|
+
* overlapping async work — like two MCP tool dispatches in flight at
|
|
625
|
+
* the same time — see their own headers without stepping on each other.
|
|
626
|
+
*/
|
|
627
|
+
private readonly requestContext;
|
|
628
|
+
/** Delegate address derived from the private key (if provided) */
|
|
629
|
+
readonly delegateAddress: string | undefined;
|
|
630
|
+
constructor(config: HavenClientConfig);
|
|
631
|
+
/**
|
|
632
|
+
* Run `fn` with extra Haven-API headers scoped to the async work it
|
|
633
|
+
* performs. Used by the MCP server to tag every Haven API request that
|
|
634
|
+
* a single tool dispatch makes with `X-Haven-MCP-Tool: <name>` so the
|
|
635
|
+
* backend can write an audit-log row attributing the call.
|
|
636
|
+
*
|
|
637
|
+
* The headers are held in an `AsyncLocalStorage` so overlapping
|
|
638
|
+
* dispatches do not leak headers into each other's requests. The store
|
|
639
|
+
* inherits across `await` boundaries, so any Haven API call made while
|
|
640
|
+
* `fn` is awaiting will pick up the right headers.
|
|
641
|
+
*
|
|
642
|
+
* Has no effect on outbound merchant requests (x402 / MPP) — those
|
|
643
|
+
* never go through the internal `request<T>` path that reads the
|
|
644
|
+
* context.
|
|
645
|
+
*/
|
|
646
|
+
withRequestContext<T>(headers: Record<string, string>, fn: () => Promise<T>): Promise<T>;
|
|
647
|
+
/**
|
|
648
|
+
* Send a payment in one call.
|
|
649
|
+
*
|
|
650
|
+
* Creates the intent, signs the hash, submits the signature,
|
|
651
|
+
* and polls until confirmed (or throws on failure/timeout).
|
|
652
|
+
*
|
|
653
|
+
* Requires `delegateKey` to be set in the client config.
|
|
654
|
+
*/
|
|
655
|
+
pay(request: PaymentRequest): Promise<PaymentResult>;
|
|
656
|
+
/**
|
|
657
|
+
* Step 1: Create a payment intent.
|
|
658
|
+
*
|
|
659
|
+
* Returns the intent with the hash to sign.
|
|
660
|
+
*/
|
|
661
|
+
createIntent(request: PaymentRequest): Promise<PaymentIntent>;
|
|
662
|
+
/**
|
|
663
|
+
* Keyless x402 construct.
|
|
664
|
+
*
|
|
665
|
+
* The non-custodial half of an x402 payment: posts the funding request to
|
|
666
|
+
* `/x402` and returns the unsigned funding hash plus the data the caller
|
|
667
|
+
* needs to build and sign the EIP-3009 merchant header itself. Crucially it
|
|
668
|
+
* does **not** sign — neither the funding hash nor the merchant header — so
|
|
669
|
+
* it works without a `delegateKey`. Both delegate signatures happen on the
|
|
670
|
+
* machine that holds the key (the edge); the hosted MCP server relays only.
|
|
671
|
+
*
|
|
672
|
+
* Use this from the hosted, keyless server. The all-in-one `authorizeX402`
|
|
673
|
+
* remains for local clients that hold the key.
|
|
674
|
+
*
|
|
675
|
+
* Throws (via the shared payment-state path) when the amount exceeds the
|
|
676
|
+
* on-chain allowance — there is nothing to sign until the user approves.
|
|
677
|
+
*/
|
|
678
|
+
createX402Intent(paymentRequired: X402PaymentRequired, options?: X402AuthorizationOptions): Promise<X402Intent>;
|
|
679
|
+
/**
|
|
680
|
+
* Step 2: Sign a hash with the delegate key.
|
|
681
|
+
*
|
|
682
|
+
* Returns the 65-byte signature (0x-prefixed).
|
|
683
|
+
* Requires `delegateKey` to be set in the client config.
|
|
684
|
+
*/
|
|
685
|
+
sign(hash: string): string;
|
|
686
|
+
/**
|
|
687
|
+
* Step 3: Submit a signature to execute the payment.
|
|
688
|
+
*
|
|
689
|
+
* The signature can come from `client.sign()` or from external signing.
|
|
690
|
+
*/
|
|
691
|
+
submitSignature(paymentId: string, signature: string): Promise<{
|
|
692
|
+
status: string;
|
|
693
|
+
txHash?: string;
|
|
694
|
+
}>;
|
|
695
|
+
/**
|
|
696
|
+
* Get the current status of a payment.
|
|
697
|
+
*/
|
|
698
|
+
getPayment(paymentId: string): Promise<PaymentResult>;
|
|
699
|
+
/**
|
|
700
|
+
* Get agent-actionable status for a payment intent or approval request.
|
|
701
|
+
*
|
|
702
|
+
* Use this for IDs returned by agent tools and machine-payment/x402 flows.
|
|
703
|
+
* `getPayment()` remains available for payment-intent-only integrations.
|
|
704
|
+
*/
|
|
705
|
+
getPaymentStatus(paymentId: string): Promise<PaymentStatusResult>;
|
|
706
|
+
/**
|
|
707
|
+
* Get the agent identity tied to this API key.
|
|
708
|
+
*/
|
|
709
|
+
getAgent(): Promise<HavenAgent>;
|
|
710
|
+
/**
|
|
711
|
+
* Get configured and on-chain allowances for the authenticated agent.
|
|
712
|
+
*/
|
|
713
|
+
getAllowances(): Promise<HavenAllowanceSummary>;
|
|
714
|
+
/**
|
|
715
|
+
* List recent machine-payment receipts/evidence for bookkeeping.
|
|
716
|
+
*/
|
|
717
|
+
listReceipts(options?: {
|
|
718
|
+
limit?: number;
|
|
719
|
+
}): Promise<HavenPaymentReceipt[]>;
|
|
720
|
+
/**
|
|
721
|
+
* Rehydrate the x402/MPP resume-state bundle for a payment id.
|
|
722
|
+
*
|
|
723
|
+
* The server returns stored protocol context only. The client still signs the
|
|
724
|
+
* merchant proof locally when resumeX402Payment() or resumeMppPayment() runs.
|
|
725
|
+
*/
|
|
726
|
+
getResumeState(paymentId: string): Promise<PaymentResumeState>;
|
|
727
|
+
/**
|
|
728
|
+
* Poll until a payment reaches a terminal status (confirmed, failed, expired).
|
|
729
|
+
*/
|
|
730
|
+
waitForConfirmation(paymentId: string): Promise<PaymentResult>;
|
|
731
|
+
/**
|
|
732
|
+
* Authorize an x402 payment.
|
|
733
|
+
*
|
|
734
|
+
* Takes the parsed PaymentRequired from a 402 response, selects a compatible
|
|
735
|
+
* option, funds the delegate wallet through Haven, and returns the standard
|
|
736
|
+
* x402 header that the merchant can verify and settle.
|
|
737
|
+
*
|
|
738
|
+
* Requires `delegateKey` to be set in the client config.
|
|
739
|
+
*/
|
|
740
|
+
authorizeX402(paymentRequired: X402PaymentRequired, options?: X402AuthorizationOptions): Promise<X402Receipt>;
|
|
741
|
+
/**
|
|
742
|
+
* Probe a paid endpoint and return its x402 quote without creating a Haven
|
|
743
|
+
* payment or approval request.
|
|
744
|
+
*/
|
|
745
|
+
quoteX402(url: string, init?: RequestInit, options?: X402AuthorizationOptions): Promise<X402Quote>;
|
|
746
|
+
/**
|
|
747
|
+
* Pay a previously inspected x402 quote and retry the exact captured request.
|
|
748
|
+
*/
|
|
749
|
+
payX402Quote(quote: X402Quote, options?: X402AuthorizationOptions): Promise<Response>;
|
|
750
|
+
private authorizeStandardX402;
|
|
751
|
+
resumeAuthorizedX402(input: ResumeAuthorizedX402Input): Promise<X402Receipt>;
|
|
752
|
+
resumeX402Payment(input: ResumeX402PaymentInput | X402ResumeState): Promise<Response>;
|
|
753
|
+
/**
|
|
754
|
+
* Fetch wrapper that automatically handles HTTP 402 responses.
|
|
755
|
+
*
|
|
756
|
+
* Works like the standard `fetch()` but intercepts 402 responses,
|
|
757
|
+
* pays via x402 through Haven, and retries the request.
|
|
758
|
+
*
|
|
759
|
+
* ```ts
|
|
760
|
+
* const response = await haven.fetch('https://paid-api.com/data')
|
|
761
|
+
* const data = await response.json()
|
|
762
|
+
* ```
|
|
763
|
+
*
|
|
764
|
+
* Requires `delegateKey` to be set in the client config.
|
|
765
|
+
*/
|
|
766
|
+
fetch(url: string, init?: RequestInit, options?: X402AuthorizationOptions): Promise<Response>;
|
|
767
|
+
/**
|
|
768
|
+
* Probe a paid MPP endpoint or inspect an existing challenge without creating
|
|
769
|
+
* a Haven payment or approval request.
|
|
770
|
+
*/
|
|
771
|
+
quoteMpp(challengeOrUrl: MachinePaymentChallenge | string, init?: RequestInit, options?: MppAuthorizationOptions): Promise<MppQuote>;
|
|
772
|
+
/**
|
|
773
|
+
* Pay a previously inspected MPP quote and retry the exact captured request.
|
|
774
|
+
*/
|
|
775
|
+
payMppChallenge(quote: MppQuote, options?: MppAuthorizationOptions): Promise<Response>;
|
|
776
|
+
private retryX402Request;
|
|
777
|
+
authorizeMachinePayment(challenge: MachinePaymentChallenge, options?: MppAuthorizationOptions): Promise<MachinePaymentReceipt>;
|
|
778
|
+
private authorizeMppDemoPayment;
|
|
779
|
+
resumeAuthorizedMpp(input: ResumeAuthorizedMppInput): Promise<MachinePaymentReceipt>;
|
|
780
|
+
resumeMppPayment(input: ResumeMppPaymentInput | MppResumeState): Promise<Response>;
|
|
781
|
+
private fetchWithMachinePayment;
|
|
782
|
+
private retryMppRequest;
|
|
783
|
+
private assertCanResumeX402;
|
|
784
|
+
private assertCanResumeMpp;
|
|
785
|
+
private mapX402ReceiptFromAuthorization;
|
|
786
|
+
private mapX402ReceiptFromStatus;
|
|
787
|
+
private buildX402Receipt;
|
|
788
|
+
private createStandardX402Header;
|
|
789
|
+
private cacheX402Receipt;
|
|
790
|
+
private mapMachinePaymentReceipt;
|
|
791
|
+
private mapMachinePaymentReceiptFromStatus;
|
|
792
|
+
private recordMerchantRetryRejected;
|
|
793
|
+
private reportMachinePaymentEvidence;
|
|
794
|
+
private throwIfNonSignableAuthorizationState;
|
|
795
|
+
private throwPaymentStateError;
|
|
796
|
+
private paymentStateFromRaw;
|
|
797
|
+
private x402PayerAddress;
|
|
798
|
+
private snapshotX402Request;
|
|
799
|
+
private snapshotRequestBody;
|
|
800
|
+
private requestInitFromSnapshot;
|
|
801
|
+
private withX402Wallet;
|
|
802
|
+
private buildX402Quote;
|
|
803
|
+
private buildX402ResumeState;
|
|
804
|
+
private buildMppQuote;
|
|
805
|
+
private buildMppResumeState;
|
|
806
|
+
private attachResumeState;
|
|
807
|
+
private attachX402ResumeState;
|
|
808
|
+
private attachMppResumeState;
|
|
809
|
+
/**
|
|
810
|
+
* Execute a tool call by name and input.
|
|
811
|
+
*
|
|
812
|
+
* Designed to plug directly into agent tool-call handlers:
|
|
813
|
+
*
|
|
814
|
+
* ```ts
|
|
815
|
+
* if (block.type === 'tool_use') {
|
|
816
|
+
* const result = await haven.executeTool(block.name, block.input)
|
|
817
|
+
* // send result back to the model
|
|
818
|
+
* }
|
|
819
|
+
* ```
|
|
820
|
+
*/
|
|
821
|
+
executeTool(toolName: string, input: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
822
|
+
private toolX402PaymentRequired;
|
|
823
|
+
private x402ToolReceipt;
|
|
824
|
+
private toolError;
|
|
825
|
+
private post;
|
|
826
|
+
private get;
|
|
827
|
+
private request;
|
|
828
|
+
private mapPaymentResult;
|
|
829
|
+
private mapPaymentStatusResult;
|
|
830
|
+
private mapPaymentReceipt;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Pre-built tool definitions for AI agent frameworks.
|
|
835
|
+
*
|
|
836
|
+
* These definitions describe Haven's direct SDK tool-calling surface in the
|
|
837
|
+
* formats expected by Claude (Anthropic) and OpenAI.
|
|
838
|
+
*
|
|
839
|
+
* The agent payment surface used by these tools is shared with the
|
|
840
|
+
* `@haven_ai/mcp` server — both consume `toolDescriptions` from
|
|
841
|
+
* `./tool-descriptions.ts`. Each consumer composes its own user-visible string
|
|
842
|
+
* from the same semantic fragments, so guidance lands in both surfaces at
|
|
843
|
+
* once and a downstream test asserts the shared summary appears in every
|
|
844
|
+
* consumer description.
|
|
845
|
+
*
|
|
846
|
+
* Usage with Claude:
|
|
847
|
+
* const response = await anthropic.messages.create({
|
|
848
|
+
* tools: havenTools.claude(),
|
|
849
|
+
* ...
|
|
850
|
+
* })
|
|
851
|
+
*
|
|
852
|
+
* Usage with OpenAI:
|
|
853
|
+
* const response = await openai.chat.completions.create({
|
|
854
|
+
* tools: havenTools.openai(),
|
|
855
|
+
* ...
|
|
856
|
+
* })
|
|
857
|
+
*/
|
|
858
|
+
interface ClaudeTool {
|
|
859
|
+
name: string;
|
|
860
|
+
description: string;
|
|
861
|
+
input_schema: {
|
|
862
|
+
type: 'object';
|
|
863
|
+
properties: Record<string, unknown>;
|
|
864
|
+
required: readonly string[];
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
declare function claudeTools(): ClaudeTool[];
|
|
868
|
+
interface OpenAITool {
|
|
869
|
+
type: 'function';
|
|
870
|
+
function: {
|
|
871
|
+
name: string;
|
|
872
|
+
description: string;
|
|
873
|
+
parameters: {
|
|
874
|
+
type: 'object';
|
|
875
|
+
properties: Record<string, unknown>;
|
|
876
|
+
required: readonly string[];
|
|
877
|
+
};
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
declare function openaiTools(): OpenAITool[];
|
|
881
|
+
declare const havenTools: {
|
|
882
|
+
/** Tool definitions in Anthropic/Claude format */
|
|
883
|
+
claude: typeof claudeTools;
|
|
884
|
+
/** Tool definitions in OpenAI function-calling format */
|
|
885
|
+
openai: typeof openaiTools;
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* Sign a hash using raw ECDSA (no Ethereum message prefix).
|
|
890
|
+
*
|
|
891
|
+
* This matches what Safe's AllowanceModule `checkSignature` expects —
|
|
892
|
+
* a direct ecrecover over the hash, NOT the "\x19Ethereum Signed Message" variant.
|
|
893
|
+
*
|
|
894
|
+
* Uses ethers.SigningKey.sign() instead of wallet.signMessage() to avoid the prefix.
|
|
895
|
+
*/
|
|
896
|
+
declare function signHash(privateKey: string, hash: string): string;
|
|
897
|
+
/**
|
|
898
|
+
* Derive the Ethereum address from a private key.
|
|
899
|
+
*/
|
|
900
|
+
declare function addressFromKey(privateKey: string): string;
|
|
901
|
+
/**
|
|
902
|
+
* Verify that a signature over a hash recovers to the expected address.
|
|
903
|
+
*/
|
|
904
|
+
declare function verifySignature(hash: string, signature: string, expectedAddress: string): boolean;
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Shared semantic descriptions for Haven agent payment tools.
|
|
908
|
+
*
|
|
909
|
+
* Two surfaces in this repo expose Haven as a tool: the Claude / OpenAI
|
|
910
|
+
* function-calling tool definitions in `tools.ts` (used for direct SDK
|
|
911
|
+
* integrations) and the MCP server in `packages/mcp` (used by any MCP-speaking
|
|
912
|
+
* agent runtime). The two surfaces use different tool *names* — the SDK's
|
|
913
|
+
* tools are tuned for tool-calling conventions (`make_payment`,
|
|
914
|
+
* `authorize_x402_payment`); the MCP tools follow the MCP `haven_*` naming
|
|
915
|
+
* (`haven_pay_x402_quote`).
|
|
916
|
+
*
|
|
917
|
+
* The underlying *operations* are the same, so the descriptive prose should
|
|
918
|
+
* live in one place. Both surfaces import from this module and compose their
|
|
919
|
+
* own tool descriptions from these semantic fragments. Drift is caught by
|
|
920
|
+
* tests asserting each consumer's description string contains the shared
|
|
921
|
+
* `summary` from this module.
|
|
922
|
+
*/
|
|
923
|
+
interface ToolDescription {
|
|
924
|
+
/** One-line summary of the operation. Used as the first sentence of every
|
|
925
|
+
* downstream description and as a stable substring for drift tests. */
|
|
926
|
+
summary: string;
|
|
927
|
+
/** Natural-language user intents that should make an agent prefer this
|
|
928
|
+
* tool over adjacent tools. Empty or omitted when the summary is enough. */
|
|
929
|
+
selectionGuidance?: string;
|
|
930
|
+
/** Concrete behaviour the tool performs end-to-end, including which
|
|
931
|
+
* non-custodial guarantee applies. */
|
|
932
|
+
behavior: string;
|
|
933
|
+
/** What the agent should do next on error / pending-approval states.
|
|
934
|
+
* Empty string if not applicable. */
|
|
935
|
+
nextActionGuidance: string;
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* Build a single description string from the three fragments. Joined with
|
|
939
|
+
* spaces so consumers can split on the summary substring if they need to.
|
|
940
|
+
*/
|
|
941
|
+
declare function composeDescription(d: ToolDescription): string;
|
|
942
|
+
declare const toolDescriptions: {
|
|
943
|
+
readonly quoteX402: {
|
|
944
|
+
readonly summary: "Inspect an HTTP 402 x402 paid resource without creating a Haven payment, signature, approval, or on-chain transaction.";
|
|
945
|
+
readonly behavior: "Probes the merchant directly and parses the 402 response. Pure read-only client behavior — Haven is not contacted.";
|
|
946
|
+
readonly nextActionGuidance: "On success the returned quote is the input to haven_pay_x402_quote. Do not call the merchant again — Haven re-uses the captured request when paying.";
|
|
947
|
+
};
|
|
948
|
+
readonly payX402: {
|
|
949
|
+
readonly summary: "Pay an inspected x402 quote. The delegate key signs locally; Haven only validates and relays signed, on-chain-constrained payment transactions.";
|
|
950
|
+
readonly selectionGuidance: "Do not use this for read-only allowance, budget, spend-limit, remaining-amount, reset-period, or what-can-I-spend questions; use the allowance lookup tool instead.";
|
|
951
|
+
readonly behavior: "Signs the EIP-3009 payment from the delegate wallet, asks Haven for a Safe AllowanceModule top-up if needed, and returns the merchant response or a pending-approval state.";
|
|
952
|
+
readonly nextActionGuidance: string;
|
|
953
|
+
};
|
|
954
|
+
readonly payX402OneShot: {
|
|
955
|
+
readonly summary: "Fetch an x402 paid HTTP resource in a single call. Handles the full probe -> pay -> retry round trip and returns the merchant response.";
|
|
956
|
+
readonly selectionGuidance: "Prefer this over the quote+pay split when the agent just wants the paid resource and does not need to inspect the price first. If you already have a quote from haven_quote_x402, use haven_pay_x402_quote instead. Do not use for read-only allowance, budget, spend-limit, remaining-amount, reset-period, or what-can-I-spend questions; use the allowance lookup tool instead.";
|
|
957
|
+
readonly behavior: "Calls the URL, parses any HTTP 402 x402 challenge, signs the EIP-3009 payment from the delegate wallet, asks Haven for a Safe AllowanceModule top-up if needed, then retries the original request with the X-PAYMENT header and returns the merchant response. If the resource returns an MPP machine-payment challenge instead of standard x402, the MPP payment path is used automatically. If the resource returns a non-402 status, returns it unchanged without contacting Haven.";
|
|
958
|
+
readonly nextActionGuidance: string;
|
|
959
|
+
};
|
|
960
|
+
readonly resumeX402: {
|
|
961
|
+
readonly summary: "Resume an x402 payment after the Haven wallet owner approved the funding step.";
|
|
962
|
+
readonly behavior: "Accepts either resume_state or payment_id, validates the original x402 details against the approved Haven funding, and retries the merchant request with the X-PAYMENT header. No new Haven approval is created.";
|
|
963
|
+
readonly nextActionGuidance: "Only use when get_payment_status returns nextAction=retry_original_x402_request; do not start a new merchant session.";
|
|
964
|
+
};
|
|
965
|
+
readonly quoteMpp: {
|
|
966
|
+
readonly summary: "Inspect a Haven MPP challenge or paid MPP URL without creating a Haven payment, signature, approval, or on-chain transaction.";
|
|
967
|
+
readonly behavior: "Parses an MPP challenge envelope and returns a typed quote with rail tag, amount, asset, and merchant context. Pure read-only — Haven is not contacted.";
|
|
968
|
+
readonly nextActionGuidance: "On success the returned quote is the input to haven_pay_mpp_challenge. Do not call the merchant again — Haven re-uses the captured request when paying.";
|
|
969
|
+
};
|
|
970
|
+
readonly payMpp: {
|
|
971
|
+
readonly summary: "Pay an inspected MPP challenge. The delegate key signs locally; Haven only validates and relays signed, on-chain-constrained payment transactions.";
|
|
972
|
+
readonly selectionGuidance: "Do not use this for read-only allowance, budget, spend-limit, remaining-amount, reset-period, or what-can-I-spend questions; use the allowance lookup tool instead.";
|
|
973
|
+
readonly behavior: "Authorizes the payment through Haven within the on-chain allowance, signs the challenge proof, and returns the proof header for retrying the original paid resource.";
|
|
974
|
+
readonly nextActionGuidance: "If approval is needed, preserve resume_state or payment_id and wait for nextAction=retry_original_x402_request before resuming.";
|
|
975
|
+
};
|
|
976
|
+
readonly resumeMpp: {
|
|
977
|
+
readonly summary: "Resume an MPP payment after the Haven wallet owner approved the funding step.";
|
|
978
|
+
readonly behavior: "Accepts either resume_state or payment_id and retries the original paid resource with the MPP proof header. No new Haven approval is created.";
|
|
979
|
+
readonly nextActionGuidance: "";
|
|
980
|
+
};
|
|
981
|
+
readonly getPaymentStatus: {
|
|
982
|
+
readonly summary: "Fetch structured Haven payment status, including phase and nextAction taxonomy for agent recovery.";
|
|
983
|
+
readonly behavior: "Accepts a payment intent or approval request id and returns the full state taxonomy (phase, nextAction, rail, amount, merchant, resource url, idempotency key, message).";
|
|
984
|
+
readonly nextActionGuidance: "";
|
|
985
|
+
};
|
|
986
|
+
readonly getResumeState: {
|
|
987
|
+
readonly summary: "Rehydrate stored x402 or MPP resume_state by payment_id.";
|
|
988
|
+
readonly behavior: "Returns the context that the agent originally received in a pending-approval response, reconstructed from Haven's database. This is context only; signing still happens locally when a resume tool is called.";
|
|
989
|
+
readonly nextActionGuidance: "";
|
|
990
|
+
};
|
|
991
|
+
readonly getAgent: {
|
|
992
|
+
readonly summary: "Return the authenticated agent identity, Haven wallet, delegate address, chain, and status.";
|
|
993
|
+
readonly behavior: "Read-only identity lookup. Useful for verifying which on-chain Safe and delegate the credential is bound to.";
|
|
994
|
+
readonly nextActionGuidance: "";
|
|
995
|
+
};
|
|
996
|
+
readonly getAllowances: {
|
|
997
|
+
readonly summary: "Return configured and on-chain allowance state for the authenticated agent. On-chain allowance is the real spend gate.";
|
|
998
|
+
readonly selectionGuidance: "Use this when the user asks about allowance, budget, spend limit, remaining amount, remaining allowance, remaining budget, daily limit, reset period, what can I spend, or what the agent can still spend.";
|
|
999
|
+
readonly behavior: "Reads the Safe AllowanceModule snapshot per token (allowance, spent, remaining, reset window). Configured amounts from Haven are returned alongside the on-chain truth.";
|
|
1000
|
+
readonly nextActionGuidance: "";
|
|
1001
|
+
};
|
|
1002
|
+
readonly listReceipts: {
|
|
1003
|
+
readonly summary: "List recent machine-payment receipts and evidence for bookkeeping.";
|
|
1004
|
+
readonly selectionGuidance: "Use this for transaction history, receipts, payment evidence, or bookkeeping; use the allowance tool instead for remaining allowance, budget, spend-limit, or what-can-I-spend questions.";
|
|
1005
|
+
readonly behavior: "Returns the agent's recent machine-payment receipts ordered by recency. Proof header values are not returned.";
|
|
1006
|
+
readonly nextActionGuidance: "";
|
|
1007
|
+
};
|
|
1008
|
+
};
|
|
1009
|
+
type SharedToolKey = keyof typeof toolDescriptions;
|
|
1010
|
+
|
|
1011
|
+
/**
|
|
1012
|
+
* x402 protocol support for the Haven SDK.
|
|
1013
|
+
*
|
|
1014
|
+
* Provides:
|
|
1015
|
+
* - parsePaymentRequired() — extract payment requirements from a 402 response
|
|
1016
|
+
* - parsePaymentRequiredResponse() — async parser with JSON body fallback
|
|
1017
|
+
* - encodePaymentProof() — encode a receipt as a PAYMENT-SIGNATURE header
|
|
1018
|
+
*
|
|
1019
|
+
* The main authorizeX402() and fetchWithPayment() are methods on HavenClient
|
|
1020
|
+
* (see client.ts) since they need API access and signing.
|
|
1021
|
+
*/
|
|
1022
|
+
|
|
1023
|
+
/**
|
|
1024
|
+
* Parse an HTTP 402 response into x402 PaymentRequired data.
|
|
1025
|
+
*
|
|
1026
|
+
* Supports:
|
|
1027
|
+
* - v2: PAYMENT-REQUIRED header (base64 JSON)
|
|
1028
|
+
* - v1 fallback: X-PAYMENT header or response body
|
|
1029
|
+
*/
|
|
1030
|
+
declare function parsePaymentRequired(response: Response): X402PaymentRequired;
|
|
1031
|
+
/**
|
|
1032
|
+
* Parse an HTTP 402 response into x402 PaymentRequired data.
|
|
1033
|
+
*
|
|
1034
|
+
* Soundside and other Bazaar-style MCP endpoints return the PaymentRequired
|
|
1035
|
+
* object in the JSON body, while older Haven demos and many x402 examples use
|
|
1036
|
+
* base64 headers. This keeps the synchronous header parser intact and adds the
|
|
1037
|
+
* body fallback needed for those endpoints.
|
|
1038
|
+
*/
|
|
1039
|
+
declare function parsePaymentRequiredResponse(response: Response): Promise<X402PaymentRequired>;
|
|
1040
|
+
/**
|
|
1041
|
+
* Select the best payment option from the x402 accepts array.
|
|
1042
|
+
*
|
|
1043
|
+
* Preference order:
|
|
1044
|
+
* 1. Option on a Haven-supported network with a known token
|
|
1045
|
+
* 2. Any option on a Haven-supported network
|
|
1046
|
+
* 3. null — no compatible option
|
|
1047
|
+
*/
|
|
1048
|
+
declare function selectPaymentOption(accepts: X402PaymentOption[]): X402PaymentOption | null;
|
|
1049
|
+
/**
|
|
1050
|
+
* Select an option that can be paid with the official x402 EIP-3009 exact
|
|
1051
|
+
* scheme. Haven's older tx-hash proof path can describe more networks; the
|
|
1052
|
+
* merchant-verified path currently needs Base USDC.
|
|
1053
|
+
*/
|
|
1054
|
+
declare function selectStandardPaymentOption(accepts: X402PaymentOption[]): X402PaymentOption | null;
|
|
1055
|
+
declare function x402AuthorizationAmount(option: X402PaymentOption): string;
|
|
1056
|
+
declare function buildX402ExpectedMessage(context: X402ExpectedContext): string;
|
|
1057
|
+
declare function toStandardPaymentRequirements(paymentRequired: X402PaymentRequired, option: X402PaymentOption): PaymentRequirements;
|
|
1058
|
+
/**
|
|
1059
|
+
* Encode a payment receipt as a base64 PAYMENT-SIGNATURE header value.
|
|
1060
|
+
*
|
|
1061
|
+
* This follows the x402 v2 protocol — the server's facilitator will
|
|
1062
|
+
* verify the on-chain transaction referenced by tx_hash.
|
|
1063
|
+
*/
|
|
1064
|
+
declare function encodePaymentProof(receipt: {
|
|
1065
|
+
txHash: string;
|
|
1066
|
+
paymentId: string;
|
|
1067
|
+
token: string;
|
|
1068
|
+
amount: string;
|
|
1069
|
+
to: string;
|
|
1070
|
+
resourceUrl?: string;
|
|
1071
|
+
accepted?: X402PaymentOption;
|
|
1072
|
+
payer?: string;
|
|
1073
|
+
chainId?: number;
|
|
1074
|
+
}): string;
|
|
1075
|
+
|
|
1076
|
+
declare function parseMachinePaymentChallenge(response: Response): MachinePaymentChallenge;
|
|
1077
|
+
declare function parseMachinePaymentChallengeResponse(response: Response): Promise<MachinePaymentChallenge>;
|
|
1078
|
+
declare function buildMachinePaymentIdempotencyKey(challenge: MachinePaymentChallenge): string;
|
|
1079
|
+
declare function encodeMachinePaymentProof(receipt: Omit<MachinePaymentReceipt, 'proofHeader'>): string;
|
|
1080
|
+
|
|
1081
|
+
export { AGENT_PAYMENT_NEXT_ACTION_VALUES, AGENT_PAYMENT_PHASE_VALUES, AGENT_PAYMENT_RAIL_VALUES, type AgentPaymentEnumSchema, AgentPaymentNextAction, AgentPaymentNextActionDescriptions, AgentPaymentNextActionSchema, AgentPaymentPhase, AgentPaymentPhaseDescriptions, AgentPaymentPhaseSchema, AgentPaymentRail, AgentPaymentRailDescriptions, AgentPaymentRailSchema, type ClaudeTool, type HavenAgent, type HavenAllowance, type HavenAllowanceSummary, HavenApiError, HavenClient, type HavenClientConfig, HavenError, type HavenPaymentReceipt, HavenPaymentStateError, HavenSigningError, HavenTimeoutError, type MachinePaymentChallenge, type MachinePaymentRail, type MachinePaymentReceipt, type MppAuthorizationOptions, type MppQuote, type MppResumeState, type OpenAITool, type PaymentIntent, type PaymentNextAction, type PaymentPhase, type PaymentRequest, type PaymentResult, type PaymentResumeState, type PaymentStatus, type PaymentStatusResult, type PendingApproval, type ResumeAuthorizedMppInput, type ResumeAuthorizedX402Input, type ResumeMppPaymentInput, type ResumeX402PaymentInput, type SharedToolKey, type SignData, type ToolDescription, type X402AuthorizationOptions, type X402ExpectedAuth, type X402ExpectedContext, type X402Intent, type X402PaymentOption, type X402PaymentRequired, type X402Quote, type X402Receipt, type X402RequestSnapshot, type X402ResumeState, addressFromKey, buildMachinePaymentIdempotencyKey, buildX402ExpectedMessage, composeDescription, encodeMachinePaymentProof, encodePaymentProof, havenTools, parseMachinePaymentChallenge, parseMachinePaymentChallengeResponse, parsePaymentRequired, parsePaymentRequiredResponse, selectPaymentOption, selectStandardPaymentOption, signHash, toStandardPaymentRequirements, toolDescriptions, verifySignature, x402AuthorizationAmount };
|